使用Next.js+SendGrid发送PDF出现文件损坏问题及解决方法
问题原因
你通过readAsDataURL生成的Base64字符串包含了数据URL前缀(格式如data:application/pdf;base64,),SendGrid会把这个前缀当作PDF文件内容的一部分,破坏了文件的原始结构,导致附件打开时显示损坏。
修复方案
1. 前端移除Base64前缀
修改handleFileSelect函数,剥离数据URL前缀,只保留纯Base64编码内容:
const handleFileSelect = async (e: React.BaseSyntheticEvent) => { const file = e.target.files[0]; const dataUrl = await toBase64(file); // 分割字符串,取逗号后的纯Base64部分 const pureBase64 = dataUrl.split(',')[1]; setSelectedFile(pureBase64); };
2. 可选优化:保留原文件名
当前代码附件文件名写死为"content",可以传递原文件名让附件显示更合理:
- 前端新增状态保存文件名,并在上传时一并传递:
// 新增状态存储文件名 const [fileName, setFileName] = useState(''); const handleFileSelect = async (e: React.BaseSyntheticEvent) => { const file = e.target.files[0]; const dataUrl = await toBase64(file); const pureBase64 = dataUrl.split(',')[1]; setSelectedFile(pureBase64); setFileName(file.name); // 保存文件原始名称 }; const handleFileUpload = async (e: any) => { e.preventDefault(); // 同时传递文件内容和文件名 const req = await axios.post("/api/email", { file: selectedFile, fileName }); };
- 后端API使用传递的文件名:
attachments: [ { content: attachment.file, filename: attachment.fileName || "content.pdf", // 优先用原文件名,兜底默认值 type: "application/pdf", disposition: "attachment", }, ],
3. 排查验证
如果修复后仍有问题,可以在前端打印pureBase64,或者后端接收后检查内容:确认没有前缀,且是有效的PDF Base64编码。
内容的提问来源于stack exchange,提问作者kapaakinos
相关产品推荐
相关产品推荐

