ASP.NET Core中通过FileResult导出PDF时偶现失效问题
问题根源
AJAX请求本身不会触发浏览器的文件下载行为,它仅负责接收服务器返回的数据;而表单提交属于浏览器原生导航行为,会自动处理FileResult对应的文件下载/预览逻辑,这就是两种场景表现不同的核心原因。
解决方案
方案一:动态创建临时表单提交(适配POST请求)
放弃AJAX,通过JS生成临时表单模拟原生提交行为,这样能直接触发浏览器的文件下载流程:
function printToPdf(printFrom) { var id = printFrom == "edit" ? $("#letterId").val() : $("#letterROId").val(); closeLetter(); // 创建临时表单 const form = document.createElement('form'); form.method = 'POST'; form.action = `/Lender/PrintLetterPdf/${id}`; // 追加防伪造令牌(ASP.NET Core默认启用验证,必须添加) const tokenInput = document.createElement('input'); tokenInput.type = 'hidden'; tokenInput.name = '__RequestVerificationToken'; tokenInput.value = $('input[name="__RequestVerificationToken"]').val(); form.appendChild(tokenInput); document.body.appendChild(form); form.submit(); document.body.removeChild(form); }
方案二:处理AJAX返回的二进制数据生成Blob下载
如果必须保留AJAX调用,需修改请求配置以接收二进制数据,再手动触发下载:
function printToPdf(printFrom) { var id = printFrom == "edit" ? $("#letterId").val() : $("#letterROId").val(); closeLetter(); const jqxhr = $.ajax({ type: "POST", url: `/Lender/PrintLetterPdf/${id}`, // 关键:指定响应类型为二进制Blob xhrFields: { responseType: 'blob' }, // 移除JSON相关配置,因为返回的是二进制PDF而非JSON contentType: false, processData: false }); jqxhr.done(function (blob) { // 创建临时下载链接 const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'Letter.pdf'; // 指定下载文件名 document.body.appendChild(a); a.click(); // 清理资源 window.URL.revokeObjectURL(url); document.body.removeChild(a); printingPdf(); }); jqxhr.fail(function () { const msg = "An error occurred while printing Letter PDF!"; ShowInfoMessage(msg, 'error'); }); }
同时确保控制器方法返回正确的MIME类型:
public IActionResult PrintLetterPdf(int id) { // 生成PDF字节数组逻辑 byte[] pdfBytes = GeneratePdfUsingSelectPdf(id); // 指定PDF的MIME类型和默认文件名 return File(pdfBytes, "application/pdf", "Letter.pdf"); }
原AJAX代码的问题说明
原代码设置datatype: "json",但服务器返回的是二进制PDF数据而非JSON格式,导致数据解析异常;同时即使请求成功,也没有编写任何触发文件下载的逻辑,因此看不到文件输出。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

