如何通过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]); } }
三、关键注意事项
- React 18适配验证:确保
package.json的overrides配置生效,执行npm install后,检查node_modules/@react-pdf/renderer/package.json中的react依赖版本为^18.2.0。 - 文件大小限制:WordPress默认有上传文件大小限制,可通过修改
php.ini的upload_max_filesize和post_max_size参数,或使用WordPress插件调整。 - 安全控制:务必保留
X-WP-Nonce验证,避免CSRF攻击;权限回调需根据业务需求严格设置,禁止无限制公开访问。
内容的提问来源于stack exchange,提问作者Simone Conti
相关产品推荐
相关产品推荐

