如何为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
相关产品推荐
相关产品推荐

