如何将JS的canvas.toDataURL结果传入PHPMailer的addAttachment作为附件
实现方案说明
核心问题:前端JS生成的base64图片存储在用户浏览器端,服务端PHP无法直接读取前端变量/DOM对象,你之前传入$(#linkImg)无效的原因就是这是前端jQuery对象,PHP无法识别。
第一步:前端传输base64数据到后端
你需要先把JS中生成的base64图片数据提交给PHP服务端,修改逻辑如下:
- 在你的HTML提交表单中增加一个隐藏字段,用于存储base64数据:
<input type="hidden" id="pngBase64" name="pngBase64">
- 修改你的
getPNG函数,把生成的base64赋值给该隐藏字段:
function getPNG(){ html2canvas(document.querySelector("#plan")).then(canvas => { document.getElementById("box1").appendChild(canvas) var url = canvas.toDataURL("image/png"); const linkImg = document.getElementById("linkImg"); linkImg.href=url.replace("image/png", "image/octet-stream"); linkImg.download="plan.png"; // 新增:把base64数据存入隐藏字段 document.getElementById("pngBase64").value = url; }); }
- 正常提交表单(method设为POST)或者通过AJAX把
pngBase64的内容发送给PHP后端即可。
第二步:PHP端处理并添加附件
PHPMailer提供两种方案添加这张动态生成的图片作为附件:
方案1:直接添加字符串附件(无需存本地文件,更推荐)
使用PHPMailer内置的addStringAttachment方法直接处理解码后的图片二进制内容:
<?php // 接收前端传过来的base64数据 $base64 = $_POST['pngBase64']; // 去除base64头部标识,解码为二进制图片数据 $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64)); // 直接添加附件,第二个参数是附件显示的文件名 $mail->addStringAttachment($imageData, 'plan.png'); ?>
方案2:存为临时文件后调用addAttachment
如果你一定要使用addAttachment方法,需要先把图片存为临时文件再传入路径:
<?php $base64 = $_POST['pngBase64']; $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64)); // 生成临时文件路径 $tmpFilePath = tempnam(sys_get_temp_dir(), 'pool_plan_') . '.png'; // 写入图片数据到临时文件 file_put_contents($tmpFilePath, $imageData); // 传入临时文件路径作为addAttachment的参数 $mail->addAttachment($tmpFilePath, 'plan.png'); // 发件完成后可手动删除临时文件,也可等待系统自动清理临时目录 // unlink($tmpFilePath); ?>
注意事项
- 请确保PHP配置的
post_max_size足够大,避免过长的base64数据被截断 - 必须等
html2canvas执行完成、base64数据赋值完成后再提交表单/发请求,避免传输不完整的图片数据 - 如果使用AJAX提交,注意设置正确的请求头,避免跨域问题
内容的提问来源于stack exchange,提问作者Etienne
相关产品推荐
相关产品推荐

