使用AJAX下载文件遇重复下载问题,需保留错误处理
解决AJAX实现文件下载的重复下载问题
你的代码出现重复下载的原因很明确:AJAX已经发起了一次GET请求获取文件,成功回调里又通过window.location=element.id再次发起相同的GET请求,相当于触发了两次下载操作。
要保留AJAX的错误处理能力,同时避免重复下载,你可以直接在AJAX成功回调中处理返回的文件二进制数据,手动触发下载,而不是再次跳转URL。具体修改如下:
修改后的JavaScript代码
const downloadFile = (element, event) => { // 阻止a标签的默认跳转行为 event.preventDefault(); $.ajax({ url: element.id, type: 'GET', // 指定响应类型为二进制blob,适配文件下载 xhrFields: { responseType: 'blob' }, success: (blob) => { // 创建临时a标签触发下载 const a = document.createElement('a'); const url = window.URL.createObjectURL(blob); // 可自定义下载文件名,这里优先取元素上的data属性,默认值为download const filename = element.dataset.filename || 'download'; a.href = url; a.download = filename; document.body.appendChild(a); a.click(); // 清理临时对象和标签,避免内存泄漏 window.URL.revokeObjectURL(url); document.body.removeChild(a); }, error: (request, msg, error) => { alert(request.responseText); } }) }
修改后的HTML元素
'<td>' + `<a id="hiddenAPIRoute" href="#" onclick="downloadFile(this, event)">Download</a>` + '</td>' +
关键说明
- 添加
xhrFields: {responseType: 'blob'}:告诉AJAX以二进制Blob格式接收文件内容,适配各类文件(文档、压缩包等)的处理需求。 - 手动创建临时a标签:通过
URL.createObjectURL将Blob转为可下载的临时URL,触发点击后立即清理资源,避免内存占用。 - 阻止默认行为:调用
event.preventDefault()避免a标签的默认跳转,防止额外的无效请求。 - 文件名自定义:如果后端在响应头返回
Content-Disposition字段,你可以从request.getResponseHeader('Content-Disposition')中解析出文件名,替换示例中的element.dataset.filename逻辑。
这样修改后,只会发起一次AJAX请求,成功时触发单次下载,错误时弹出提示,既解决了重复下载问题,又保留了你需要的错误处理能力。
内容的提问来源于stack exchange,提问作者Yasmine Rico
相关产品推荐
相关产品推荐

