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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:12:20