You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
?>

关键修改点说明

  1. 前端Blob传输:直接传递二进制数据,避免Base64编码解码的损耗和错误
  2. 后端二进制写入:使用wb模式打开文件,确保PDF二进制数据不被文本编码转换破坏
  3. Base64解码:如果保留Base64传递,必须用base64_decode还原二进制数据,不能直接写入字符串

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:22:57