如何在Cloudflare Workers中处理Postal-Mime解析的二进制Zip附件
解决Cloudflare Workers中传输Zip二进制附件的问题
问题原因
直接将Uint8Array类型的Zip附件内容放入JSON序列化时,JSON会将其转换为空数组(JSON不原生支持二进制类型);用TextDecoder转成UTF-8文本则会破坏Zip的二进制结构(Zip包含非UTF-8字节序列),导致文件无效。
解决方案
把Uint8Array格式的Zip内容编码为Base64字符串——JSON可完美处理字符串类型,且Base64能无损保留二进制数据结构。服务器端收到后,再将Base64字符串解码回二进制即可还原有效Zip文件。
代码修改
- 添加
Uint8Array转Base64的工具函数 - 调整附件处理逻辑,对Zip附件进行Base64编码
- 服务器端配套解码Base64字符串为二进制文件
修改后的完整代码:
import PostalMime from 'postal-mime'; // Uint8Array转Base64工具函数 function uint8ArrayToBase64(u8Arr) { return btoa(String.fromCharCode(...u8Arr)); } export default { async email(message, env, ctx) { const parser = new PostalMime(); const email = await parser.parse(message.raw); console.log('Subject', email.subject); console.log('HTML', email.html); const webhookUrl = 'https://example.com/webhook'; let attach; let attach_binary; // 遍历附件,分别处理Zip和普通CSV for (const attachment of email.attachments) { console.log('Attachment', attachment.filename); if (attachment.mimeType === 'application/zip') { // 将Zip的Uint8Array转成Base64字符串 attach_binary = uint8ArrayToBase64(attachment.content); } else if (attachment.mimeType.includes('csv')) { // 普通CSV用UTF-8解码 const decoder = new TextDecoder('utf-8'); attach = decoder.decode(attachment.content); } } const webhookPayload = JSON.stringify({ subject: email.subject, sender: message.from, email_html: email.html, email_text: email.text, email: message.to, csv: attach, csv_binary: attach_binary }); try { const response = await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: webhookPayload, }); if (response.ok) { console.log('Webhook request successful'); } else { console.error('Webhook request failed:', response.status); } } catch (error) { console.error('Error sending webhook request:', error); } }, };
服务器端解码示例(Node.js)
收到Base64字符串后,转回二进制并保存为Zip文件:
// 假设req.body是解析后的JSON payload const zipBase64 = req.body.csv_binary; const zipBuffer = Buffer.from(zipBase64, 'base64'); // 保存到本地或处理内容 fs.writeFileSync('received.zip', zipBuffer);
注意事项
- 若Zip附件体积过大,
String.fromCharCode(...u8Arr)可能存在性能问题,可改用分块处理的Base64编码函数避免一次性扩展大数组 - 服务器端需确保设置文件MIME类型为
application/zip,避免解析错误
内容的提问来源于stack exchange,提问作者Mark Walker
相关产品推荐
相关产品推荐

