JSPDF通过wp_mail发送PDF附件时特殊字符乱码问题求助
问题分析与解决方案
问题核心在于:前端jsPDF生成的PDF直接保存时丹麦字符正常,但通过AJAX传递给PHP后端并写入文件后,邮件附件中的字符乱码。这是因为jsPDF.output()默认返回Base64编码的字符串,直接将其写入文件会导致二进制PDF数据损坏,同时文件打开模式错误也会加剧编码问题。
方案一:前端传递Blob对象(推荐,高效且避免编码错误)
修改前端代码
将jsPDF输出的Base64字符串改为Blob二进制对象,通过FormData直接传输:
function sendmail() { var doc = new jsPDF('p', 'pt', 'a4'); var con1 = document.getElementById("dispID1"); doc.fromHTML(con1, 10, 10); doc.save("file.pdf"); // 前端测试保存正常 // 生成Blob二进制对象而非Base64字符串 var pdfBlob = doc.output('blob'); var data = new FormData(); // 以文件形式追加到FormData data.append("pdf_file", pdfBlob, "test.pdf"); var mailid = document.getElementById('mailadd').value; var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var mailresp = this.responseText; } } xmlhttp.open("POST", "/sendmailattach.php?q=" + mailid, true); xmlhttp.send(data); }
修改后端PHP代码
通过$_FILES接收上传的Blob文件,确保二进制数据完整:
<?php require __DIR__ . '/wp-load.php'; $hint = ""; $filename = __DIR__ . DIRECTORY_SEPARATOR . "test.pdf"; $attachment = []; // 接收前端传来的Blob文件 if(isset($_FILES['pdf_file']) && $_FILES['pdf_file']['error'] == UPLOAD_ERR_OK){ // 移动临时文件到指定路径 move_uploaded_file($_FILES['pdf_file']['tmp_name'], $filename); $attachment = [$filename]; } else { $hint = "No Data Sent"; } // 处理邮件发送 $q = $_REQUEST["q"]; $to = $q; $subject = 'This email has attachment'; $body = "<html> <body> <p> These are the danish characters “å æ ø ” that needs be sent as PDF attachment-but appearing in email</p> </body> </html>"; $headers = array('Content-Type: text/html; charset=UTF-8'); if(!empty($attachment)){ wp_mail( $to, $subject, $body, $headers, $attachment ); } // 删除临时文件 if(file_exists($filename)){ unlink($filename); } echo $hint; ?>
方案二:保持前端Base64传递,后端解码(兼容现有逻辑)
如果不想修改前端,只需调整后端对Base64数据的处理:
<?php require __DIR__ . '/wp-load.php'; $hint = ""; $filename = __DIR__ . DIRECTORY_SEPARATOR . "test.pdf"; $attachment = []; if(!empty($_POST['data'])){ // 将Base64字符串解码为二进制PDF数据 $pdfData = base64_decode($_POST['data']); // 以二进制写入模式打开文件(关键:避免文本编码转换) $in = fopen($filename, "wb"); if($in){ fwrite($in, $pdfData); fclose($in); $attachment = [$filename]; } else { $hint = "Failed to create PDF file"; } } else { $hint = "No Data Sent"; } // 处理邮件发送 $q = $_REQUEST["q"]; $to = $q; $subject = 'This email has attachment'; $body = "<html> <body> <p> These are the danish characters “å æ ø ” that needs be sent as PDF attachment-but appearing in email</p> </body> </html>"; $headers = array('Content-Type: text/html; charset=UTF-8'); if(!empty($attachment)){ wp_mail( $to, $subject, $body, $headers, $attachment ); } // 删除临时文件 if(file_exists($filename)){ unlink($filename); } echo $hint; ?>
关键修改点说明
- 前端Blob传输:直接传递二进制数据,避免Base64编码解码的损耗和错误
- 后端二进制写入:使用
wb模式打开文件,确保PDF二进制数据不被文本编码转换破坏 - Base64解码:如果保留Base64传递,必须用
base64_decode还原二进制数据,不能直接写入字符串
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

