You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-PDF <Image />无法渲染API/CDN外部图片的解决咨询

在Next.js中用React-PDF渲染外部API/CDN图片的解决方案

核心原因

React-PDF在Next.js环境下(尤其是服务端渲染场景)处理外部图片时,会遇到跨域限制或底层资源加载逻辑限制:浏览器能访问的跨域图片,服务端生成PDF时可能因CORS策略无法获取;同时React-PDF的<Image>组件对带自定义请求头的URI支持有限。

可行解决方案

1. 用Next.js API路由代理外部图片(推荐)

通过Next.js的API路由作为中间层,代理请求外部图片,绕开CORS和React-PDF的资源加载限制。

步骤1:创建代理API路由

在pages/api/proxy-image.js中添加以下代码:

import axios from 'axios';
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req, res) {
  const { url } = req.query;
  if (!url || typeof url !== 'string') {
    return res.status(400).send('缺少图片URL参数');
  }

  try {
    const response = await axios.get(decodeURIComponent(url), { 
      responseType: 'arraybuffer' 
    });
    res.setHeader('Content-Type', response.headers['content-type']);
    res.send(response.data);
  } catch (err) {
    res.status(500).send('获取图片失败');
  }
}

步骤2:在PDF组件中使用代理URL

修改你的PDF组件,将外部图片地址替换为代理路由:

import { Document, Page, Image, Text, View } from "@react-pdf/renderer";

export default function AgreementPDF() {
  const externalImageUrl = "https://example.com/uploads/seal.png";
  const proxyUrl = `/api/proxy-image?url=${encodeURIComponent(externalImageUrl)}`;

  return (
    <Document>
      <Page size="A4">
        <View>
          <Text>External seal image:</Text>
          <Image
            style={{ width: 100, height: 100 }}
            src={proxyUrl}
          />
        </View>
      </Page>
    </Document>
  );
}

2. 服务端预转换图片为Base64

如果代理方案不适用,可以在服务端提前将外部图片转换为Base64格式,再传入React-PDF的<Image>组件(避免客户端跨域问题)。

示例代码(结合Next.js的getServerSideProps):

import { Document, Page, Image, Text, View } from "@react-pdf/renderer";
import axios from 'axios';

export async function getServerSideProps() {
  const imageUrl = "https://example.com/uploads/seal.png";
  try {
    const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
    const base64Str = Buffer.from(response.data).toString('base64');
    const imageSrc = `data:${response.headers['content-type']};base64,${base64Str}`;
    
    return { props: { imageSrc } };
  } catch (err) {
    return { props: { imageSrc: '' } };
  }
}

export default function AgreementPDF({ imageSrc }) {
  return (
    <Document>
      <Page size="A4">
        <View>
          <Text>External seal image:</Text>
          {imageSrc && (
            <Image
              style={{ width: 100, height: 100 }}
              src={imageSrc}
            />
          )}
        </View>
      </Page>
    </Document>
  );
}

3. 检查CDN/CORS配置

如果你的外部图片存储在CDN上,确认CDN的CORS配置是否允许你的Next.js域名访问:

  • 确保CDN返回的响应头包含Access-Control-Allow-Origin,值为你的域名或*
  • 若CDN不支持CORS,只能通过代理或服务端转Base64的方式解决

为什么你之前的尝试无效?

  • 客户端转Base64:受浏览器跨域策略限制,无法获取跨域图片资源
  • 自定义请求头:React-PDF的<Image>组件在处理URI对象时,底层加载逻辑可能忽略自定义请求头,导致请求失败
  • 本地图片:public/文件夹下的资源属于同域资源,不受CORS限制,因此能正常渲染

内容的提问来源于stack exchange,提问作者BINARY TECH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:13:12