You need to enable JavaScript to run this app. 如何为XMLHttpRequest实现的导出方法添加Promise then回调支持
优惠活动
大模型
产品
解决方案
定价
更多

如何为XMLHttpRequest实现的导出方法添加Promise then回调支持

解决方案

核心思路是将原有的XMLHttpRequest逻辑包裹在Promise实例中返回,Promise原生支持then/catch链式调用规则,完全匹配你的使用需求。

改造后的完整exportfile代码

function exportfile(methodtype, url, model) {
    // 返回Promise实例,支持then链式调用
    return new Promise((resolve, reject) => {
        var qs = "?";
        model.forEach((item) => { // 原代码用map做遍历不合理,改用forEach更合适
            qs = `${qs}${encodeURIComponent(item.name)}=${encodeURIComponent(item.value)}&`;
        });
        // 去掉末尾多余的&
        qs = qs.slice(0, -1);

        var request = new XMLHttpRequest();
        request.open(methodtype, url + qs, true);
        request.setRequestHeader('Authorization', "Bearer " + window.localStorage.getItem('token'));
        request.responseType = 'blob';

        // 请求成功回调
        request.onload = function (e) {
            if (this.status === 200) {
                var blob = this.response;
                const fileName = "Export.xls"; // 原代码缺失fileName变量定义,这里补全
                if (window.navigator.msSaveOrOpenBlob) {
                    window.navigator.msSaveBlob(blob, fileName);
                } else {
                    var downloadLink = window.document.createElement('a');
                    var contentTypeHeader = request.getResponseHeader("Content-Type");
                    downloadLink.href = window.URL.createObjectURL(new Blob([blob], { type: contentTypeHeader }));
                    downloadLink.download = fileName;
                    document.body.appendChild(downloadLink);
                    downloadLink.click();
                    document.body.removeChild(downloadLink);
                    // 释放blob对象占用的内存,避免内存泄漏
                    window.URL.revokeObjectURL(downloadLink.href);
                }
                // 请求+下载逻辑执行完成后,将Promise状态改为已完成,触发then回调
                resolve({ status: this.status, blob: blob });
            } else {
                // 接口返回非200状态码时抛出错误
                reject(new Error(`请求失败,状态码:${this.status}`));
            }
        };

        // 请求异常回调(网络错误、跨域等问题触发)
        request.onerror = function (e) {
            reject(new Error(`请求发生异常:${e.toString()}`));
        };

        request.send();
    });
}

改动点说明

  • 原方法直接返回XHR实例,改为返回Promise实例,原生支持then链式调用
  • 修复原代码的几个隐性问题:
    • 参数名mehtodtype拼写错误改为methodtype
    • 遍历参数用forEach替代不合适的map
    • 对查询参数做encodeURIComponent编码,避免特殊字符导致请求异常
    • 补全缺失的fileName变量定义
    • 新增revokeObjectURL逻辑释放内存,避免内存泄漏
  • 新增错误处理逻辑:请求异常、非200状态码都会触发reject,可通过catch捕获处理

调用方式说明

你原有调用逻辑可以直接复用,建议补充catch处理异常场景:

dataService.exportfile('get', '/api/overtimeedari/exporttoexcle/', model)
.then(() => {
    self.loading(false);
    buttonListSearch.Excel.loading(false);
})
.catch((err) => {
    // 异常处理,比如提示用户导出失败
    console.error('导出失败:', err);
    self.loading(false);
    buttonListSearch.Excel.loading(false);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 12:39:00