如何让Ext.Ajax.request正确处理返回的application/pdf响应?
解决Ext.Ajax.request无法正确接收PDF响应的问题
我明白你的困扰——虽然后端返回了200状态码的PDF文件,但Ext.Ajax的默认逻辑会把响应当成JSON来解析,二进制PDF显然无法被解析成有效JSON,所以即便HTTP状态正常,也会触发failure回调。下面是具体的原因分析和解决方案:
为什么会进入failure回调?
Ext.Ajax的success/failure判断不只是看HTTP状态码:它默认会尝试将响应内容解析为JSON(毕竟Ext的Ajax工具主要为JSON API设计)。当返回的是二进制PDF时,解析过程必然失败,从而触发failure回调,哪怕状态码是200。
解决方案1:在failure回调中手动处理PDF响应
既然我们知道这是"假失败",可以在回调里检查HTTP状态码,手动处理PDF blob:
Ext.Ajax.useDefaultXhrHeader = false; Ext.Ajax.request({ url: '/index.php/abc/xyz?value=' + value, method: 'GET', waitMsg: 'Printing Label', responseType: 'blob', // 关键:告诉XHR以二进制blob形式接收响应 success: function (response) { // 注意:这个回调大概率不会触发,因为Ext会尝试解析JSON失败 console.log("Success!!"); }, failure: function (response) { // 手动验证HTTP状态码,判断是否是"假失败" if (response.status === 200) { // 将blob转换为可访问的URL,实现下载或预览 const pdfBlob = response.response; const blobUrl = window.URL.createObjectURL(pdfBlob); // 方案A:在新窗口打开PDF预览 window.open(blobUrl); // 方案B:创建a标签触发下载(推荐) const downloadLink = document.createElement('a'); downloadLink.href = blobUrl; downloadLink.download = 'label.pdf'; // 设置下载文件名 document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); // 释放blob URL资源,避免内存泄漏 window.URL.revokeObjectURL(blobUrl); } else { // 这里处理真正的请求错误 console.log("请求真的出错了,状态码:", response.status); } } });
解决方案2:使用原生XMLHttpRequest绕过Ext的自动解析
如果觉得Ext.Ajax的封装限制太多,直接用原生XHR会更直观,完全避开Ext的JSON解析逻辑:
const xhr = new XMLHttpRequest(); xhr.open('GET', '/index.php/abc/xyz?value=' + value, true); xhr.responseType = 'blob'; // 指定响应类型为blob xhr.onload = function() { if (xhr.status === 200) { const pdfBlob = xhr.response; const blobUrl = window.URL.createObjectURL(pdfBlob); // 触发下载 const downloadLink = document.createElement('a'); downloadLink.href = blobUrl; downloadLink.download = 'label.pdf'; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); window.URL.revokeObjectURL(blobUrl); } else { console.log("请求失败,状态码:", xhr.status); } }; xhr.onerror = function() { console.log("网络请求出错"); }; // 发送请求 xhr.send();
关键注意点
- 必须设置
responseType: 'blob',这样XHR才会把二进制PDF数据保存为Blob对象,而不是尝试转成字符串(responseText),避免乱码或解析错误。 - 处理完Blob后记得调用
window.URL.revokeObjectURL()释放资源,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Nagarajan Shanmuganathan
相关产品推荐
相关产品推荐

