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

如何通过react-pdf自动将PDF文件保存到服务器?

解决方案:在浏览器环境中将react-pdf生成的PDF存储到服务器并实现重定向

你遇到的render is a Node specific API错误,本质原因是该方法仅适用于Node.js后端环境——浏览器无法直接操作服务器文件系统,必须通过后端接口上传生成的Blob文件来完成存储需求。以下是具体实现步骤:


一、前端修改:上传Blob到后端接口

在usePDF生成Blob后,将其包装为FormData,通过fetch发送到后端接口,成功后触发页面重定向。修改你的MyPdfComponent代码如下:

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

// 样式定义(保留你的原有代码)
const styles = StyleSheet.create({ /* 你的样式 */ });

// PDF文档组件(保留你的原有代码)
const MyDocument = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque, reprehenderit!</Text>
      </View>
      <View style={styles.section}>
        <Text>Lorem ipsum dolor sit amet consectetur adipisicing elit.</Text>
      </View>
    </Page>
  </Document>
);

const MyPdfComponent = () => {
  const [instance, updateInstance] = usePDF({ document: <MyDocument /> });
  const [isUploading, setIsUploading] = React.useState(false);

  React.useEffect(() => {
    // 当Blob生成且未处于上传状态时,执行上传逻辑
    if (instance.blob && !isUploading) {
      setIsUploading(true);
      uploadPdfToServer(instance.blob);
    }
  }, [instance.blob, isUploading]);

  const uploadPdfToServer = async (pdfBlob) => {
    try {
      const formData = new FormData();
      // 为PDF文件添加自定义文件名(带时间戳避免重复)
      formData.append('pdfFile', pdfBlob, `generated-pdf-${Date.now()}.pdf`);

      // 发送请求到WordPress自定义REST API端点
      const response = await fetch('/wp-json/custom/v1/save-pdf', {
        method: 'POST',
        body: formData,
        // 携带WordPress安全验证nonce(需确保前端能获取到wpApiSettings.nonce)
        headers: {
          'X-WP-Nonce': window.wpApiSettings?.nonce || ''
        }
      });

      if (!response.ok) throw new Error('PDF上传失败');

      // 上传成功后重定向到自定义成功页面
      window.location.href = '/pdf-save-success/';
    } catch (error) {
      console.error('上传出错:', error);
      // 这里可添加前端错误提示逻辑
      setIsUploading(false);
    }
  };

  if (instance.loading || isUploading) return <div>处理中...</div>;
  if (instance.error) return <div>生成PDF出错: {instance.error}</div>;

  return null;
};

export default MyPdfComponent;

二、后端实现:WordPress自定义REST API处理文件存储

因为你的应用嵌入WordPress,直接通过WordPress的REST API实现文件接收和存储最便捷。在主题的functions.php中添加以下代码:

// 注册自定义REST API端点
add_action('rest_api_init', function () {
  register_rest_route('custom/v1', '/save-pdf', [
    'methods' => 'POST',
    'callback' => 'handle_pdf_upload',
    'permission_callback' => function () {
      // 根据需求设置权限:允许所有登录用户则返回current_user_can('edit_posts'),公开访问返回true
      return current_user_can('edit_posts');
    }
  ]);
});

function handle_pdf_upload($request) {
  // 检查是否存在上传文件
  if (!isset($_FILES['pdfFile'])) {
    return new WP_Error('missing_file', '未检测到上传文件', ['status' => 400]);
  }

  $uploaded_file = $_FILES['pdfFile'];
  // 指定存储目录(WordPress上传文件夹下的custom-pdfs子目录)
  $wp_upload_dir = wp_upload_dir();
  $target_dir = $wp_upload_dir['basedir'] . '/custom-pdfs/';

  // 若目录不存在则创建
  if (!file_exists($target_dir)) {
    mkdir($target_dir, 0755, true);
  }

  $target_file_path = $target_dir . basename($uploaded_file['name']);

  // 移动临时文件到目标目录
  if (move_uploaded_file($uploaded_file['tmp_name'], $target_file_path)) {
    return [
      'success' => true,
      'file_path' => $target_file_path,
      'file_url' => $wp_upload_dir['baseurl'] . '/custom-pdfs/' . basename($uploaded_file['name'])
    ];
  } else {
    return new WP_Error('save_failed', '文件存储失败', ['status' => 500]);
  }
}

三、关键注意事项

  1. React 18适配验证:确保package.json的overrides配置生效,执行npm install后,检查node_modules/@react-pdf/renderer/package.json中的react依赖版本为^18.2.0。
  2. 文件大小限制:WordPress默认有上传文件大小限制,可通过修改php.ini的upload_max_filesize和post_max_size参数,或使用WordPress插件调整。
  3. 安全控制:务必保留X-WP-Nonce验证,避免CSRF攻击;权限回调需根据业务需求严格设置,禁止无限制公开访问。

内容的提问来源于stack exchange,提问作者Simone Conti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:45:31