通过Ajax调用mPDF动态生成PDF时文件名显示异常问题
解决WordPress中mPDF生成PDF新窗口打开文件名错误的问题
问题根源
你遇到的核心问题是Ajax请求无法将PHP返回的HTTP头信息传递给新窗口。当你用Ajax获取PDF内容时,浏览器只会处理Ajax响应的头,新窗口打开的是你手动传递的二进制内容,完全不知道Content-Disposition头里设置的文件名;而直接用D参数触发下载,是强制浏览器直接下载,跳过了打开预览的环节。
方案1:放弃Ajax,直接打开生成PDF的PHP文件(最简单)
不需要用Ajax绕弯,直接让按钮点击事件打开open-pdf.php,同时传递生成PDF所需的参数(比如内容ID),PHP输出正确的HTTP头即可让浏览器识别PDF并显示指定文件名。
前端JS代码
document.getElementById('pdf-button').addEventListener('click', function() { // 传递生成PDF需要的参数(示例用content_id,根据你的实际需求调整) const urlParams = new URLSearchParams({ content_id: 123, _wpnonce: wpApiSettings.nonce // WordPress CSRF验证,必须加 }); // 打开新窗口加载PDF生成页面 window.open(`/wp-content/plugins/your-plugin/open-pdf.php?${urlParams.toString()}`, '_blank'); });
open-pdf.php代码
<?php // 加载WordPress环境,确保能访问WP函数和内容 require_once('../../../wp-load.php'); // 验证CSRF非ce check_admin_referer('your-plugin-nonce'); // 获取参数并生成HTML内容(示例用文章内容,根据你的实际逻辑调整) $content_id = isset($_GET['content_id']) ? intval($_GET['content_id']) : 0; $html_content = get_post_field('post_content', $content_id); // 初始化mPDF require_once('vendor/autoload.php'); $mpdf = new \Mpdf\Mpdf(); $mpdf->WriteHTML($html_content); // 设置关键HTTP头,强制浏览器识别PDF并显示指定文件名 header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="news.pdf"'); header('Cache-Control: private, max-age=0, must-revalidate'); header('Pragma: public'); // 输出PDF(用"I"参数表示inline预览) $mpdf->Output('news.pdf', 'I'); exit;
方案2:用Ajax生成临时PDF文件,返回URL打开新窗口(适合需要先处理前端数据的场景)
如果必须用Ajax先处理前端数据,可让PHP将PDF保存到服务器临时目录,返回临时文件的URL,前端再用这个URL打开新窗口。
前端JS代码
document.getElementById('pdf-button').addEventListener('click', function() { fetch('/wp-content/plugins/your-plugin/generate-pdf.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-WP-Nonce': wpApiSettings.nonce }, body: 'content_html=' + encodeURIComponent(document.getElementById('pdf-content').innerHTML) }) .then(res => res.json()) .then(data => { if (data.success && data.pdf_url) { window.open(data.pdf_url, '_blank'); // 5分钟后自动清理临时文件(可选) setTimeout(() => { fetch('/wp-content/plugins/your-plugin/clean-temp-pdf.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-WP-Nonce': wpApiSettings.nonce }, body: 'file=' + encodeURIComponent(data.file_name) }); }, 300000); } }); });
generate-pdf.php代码
<?php require_once('../../../wp-load.php'); check_ajax_referer('your-plugin-nonce', 'X-WP-Nonce'); // 获取前端传递的HTML内容 $html_content = isset($_POST['content_html']) ? urldecode($_POST['content_html']) : ''; // 初始化mPDF require_once('vendor/autoload.php'); $mpdf = new \Mpdf\Mpdf(); $mpdf->WriteHTML($html_content); // 创建临时目录(需要确保目录可写) $temp_dir = WP_CONTENT_DIR . '/uploads/temp-pdfs/'; if (!file_exists($temp_dir)) { mkdir($temp_dir, 0755, true); } // 生成唯一文件名(避免同时生成的文件互相覆盖) $file_name = 'news-' . uniqid() . '.pdf'; $file_path = $temp_dir . $file_name; // 保存PDF到临时文件 $mpdf->Output($file_path, 'F'); // 返回临时文件的访问URL $pdf_url = WP_CONTENT_URL . '/uploads/temp-pdfs/' . $file_name; wp_send_json_success(['pdf_url' => $pdf_url, 'file_name' => $file_name]);
clean-temp-pdf.php代码
<?php require_once('../../../wp-load.php'); check_ajax_referer('your-plugin-nonce', 'X-WP-Nonce'); $file_name = isset($_POST['file']) ? sanitize_text_field($_POST['file']) : ''; $temp_dir = WP_CONTENT_DIR . '/uploads/temp-pdfs/'; $file_path = $temp_dir . $file_name; // 安全校验:确保文件在临时目录内,防止路径遍历 if (file_exists($file_path) && strpos($file_path, $temp_dir) === 0) { unlink($file_path); } wp_send_json_success();
内容的提问来源于stack exchange,提问作者Cnoslen
相关产品推荐
相关产品推荐

