如何将远程文件路径转换为Base64用于邮件附件?
解决SendGrid附件Base64编码错误问题
你的问题出在给attachments[0].content赋值的是data URI格式的字符串,但SendGrid的API要求的是纯Base64编码的文件内容,不需要data:${contentType};base64,这个前缀。
修正步骤:
- 去掉
data:前缀和MIME类型部分,直接把Base64编码后的字符串赋值给content - 确保
filename带上正确的文件扩展名(比如.png),方便收件方识别文件类型
修正后的关键代码片段:
await axios.get(attachmentUrl, {responseType: "arraybuffer"}) .then(response => { const contentType = response.headers["content-type"]; const dataString = Buffer.from(response.data).toString("base64"); // 直接赋值纯Base64内容,去掉data URI前缀 emailOptions.attachments[0].content = dataString; emailOptions.attachments[0].type = contentType; // 修正文件名,带上扩展名 emailOptions.attachments[0].filename = 'Cover_Go_Studio.png'; });
完整修正后的控制器代码:
'use strict' const axios = require("axios"); module.exports = { send: async (ctx) => { const body = ctx.request.body const sendTo = 'vupd@hihi.com' strapi.log.debug(`Trying to send an email to ${sendTo}`) const attachmentUrl ='https://cms.gstech.space/uploads/Cover_Go_Studio_204fca7084.png' try { const emailOptions = { to: sendTo, subject: 'Test', text:"Test", attachments:[{ content: undefined, filename: 'Cover_Go_Studio.png', type: undefined, disposition: "attachment", }] }; await axios.get(attachmentUrl, {responseType: "arraybuffer"}) .then(response => { const contentType = response.headers["content-type"]; const dataString = Buffer.from(response.data).toString("base64"); emailOptions.attachments[0].content = dataString; emailOptions.attachments[0].type = contentType; }); await strapi.plugins['email'].services.email.send(emailOptions) strapi.log.debug(`Email sent to ${sendTo}`) ctx.send({ message: 'Email sent' }) } catch (err) { strapi.log.error(`Error sending email to ${sendTo}`, err) ctx.send({ error: 'Error sending email' }) } } }
补充说明:
- 远程文件不能用
fs.readFileSync是正常的,fs模块仅能读取本地文件系统的文件,你用axios请求远程资源并转arraybuffer的思路是正确的 - 若axios请求失败,可在catch块中增加针对性的日志输出,便于排查网络或资源访问问题
内容的提问来源于stack exchange,提问作者BinChanhKun
相关产品推荐
相关产品推荐

