HTML2Canvas生成图片添加至EML文件失败:格式不支持问题
解决EML文件格式不兼容问题
问题根源
你的代码在构建EML文件时犯了几个格式规范错误,导致邮件客户端无法识别:
- 边界标记定义与实际使用不统一
- 邮件头字段缺少必要换行,导致字段合并
- 生成Blob时用了错误的MIME类型
- Base64编码未遵循RFC规范(长串未换行)
- 误用了原始图片的Base64数据(应该用压缩后的)
修正后的代码
onInitiateExitProcess() { if (this.ToEmail) { const modalContent = document.querySelector('.email') as HTMLElement; html2canvas(modalContent).then(canvas => { const imageData = canvas.toDataURL(); this.sendEmail(imageData); }); } // 调用接口更新exitProcessInitiated状态 this.initiateExitProcess.emit(); this.updateExitProcessInitiation(); } sendEmail(imageData: string) { const subject = 'Exit Process Information'; const body = 'Please find the attached information about your assigned items.'; const img = new Image(); img.src = imageData; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 图片压缩逻辑保留 const maxWidth = 600; const maxHeight = 500; let width = img.width; let height = img.height; if (width > maxWidth) { height *= maxWidth / width; width = maxWidth; } if (height > maxHeight) { width *= maxHeight / height; height = maxHeight; } canvas.width = width; canvas.height = height; ctx?.drawImage(img, 0, 0, width, height); // 使用压缩后的图片数据 const resizedImageData = canvas.toDataURL('image/png'); const resizedBase64 = resizedImageData.split(',')[1]; // 给Base64编码按RFC规范换行(每76字符) const formattedBase64 = resizedBase64.replace(/(.{76})/g, '$1\r\n'); // 定义边界标记(注意:boundary值不要带前后--) const boundary = 'boundary_text_string'; let emailContent = `From: "Exit System" <no-reply@yourdomain.com>\r\n`; emailContent += `Bcc: ${this.ToEmail}\r\n`; emailContent += `Subject: ${subject}\r\n`; emailContent += `X-Unsent: 1\r\n`; emailContent += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n`; emailContent += `MIME-Version: 1.0\r\n`; emailContent += '\r\n'; // 正文部分 emailContent += `--${boundary}\r\n`; emailContent += `Content-Type: text/html; charset=UTF-8\r\n`; emailContent += '\r\n'; emailContent += `${body}\r\n`; emailContent += '\r\n'; // 附件部分 emailContent += `--${boundary}\r\n`; emailContent += `Content-Type: image/png; name="assigned_items.png"\r\n`; emailContent += `Content-Transfer-Encoding: base64\r\n`; emailContent += `Content-Disposition: attachment; filename="assigned_items.png"\r\n`; emailContent += '\r\n'; emailContent += `${formattedBase64}\r\n`; emailContent += '\r\n'; // 结束边界 emailContent += `--${boundary}--\r\n`; // 使用正确的MIME类型生成Blob const blobData = new Blob([emailContent], { type: 'message/rfc822' }); const link = document.createElement('a'); link.href = window.URL.createObjectURL(blobData); link.download = 'email_draft.eml'; link.click(); // 释放URL对象,避免内存泄漏 window.URL.revokeObjectURL(link.href); }; }
关键修改说明
- 统一边界标记:boundary值设为纯字符串,分隔线用
--${boundary},结束线用--${boundary}--,符合MIME规范 - 修复邮件头格式:每个字段后用
\r\n(EML要求的换行符),附件的Content-Type行末尾添加换行,避免字段合并 - 修正Blob类型:用
message/rfc822替代text/plain,让邮件客户端正确识别为EML格式 - 规范Base64编码:给长Base64串每76字符加换行,符合RFC 2045标准
- 使用压缩后的图片数据:替换成压缩后的resizedBase64,避免附件体积过大
- 添加必要邮件头:补充
From和MIME-Version字段,完善EML结构 - 释放URL对象:调用
revokeObjectURL避免内存泄漏
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

