如何通过带自定义请求头的AJAX实现文件下载
完整AJAX实现带自定义请求头的文件下载方案
我懂你的需求——原来用window.open()能正常触发下载,但没法携带自定义请求头,所以得换AJAX方案。核心思路其实是用AJAX请求拿到文件的Blob数据,再通过前端创建临时下载链接来触发浏览器的下载行为,下面给你两种可行的完整实现:
方案一:使用Fetch API(推荐,更现代简洁)
async function downloadFileWithHeaders() { try { const downloadUrl = buildRequestUrl(); // 发送带自定义头的请求 const response = await fetch(downloadUrl, { method: 'GET', // 根据实际需求换成POST等其他方法 headers: { 'X-Custom-Token': 'your-auth-token', 'X-User-Id': '12345' // 这里添加所有你需要的自定义请求头 } }); if (!response.ok) { throw new Error(`请求失败: ${response.status} ${response.statusText}`); } // 从响应头提取文件名(后端需返回Content-Disposition头) let fileName = 'downloaded-file'; const contentDisposition = response.headers.get('Content-Disposition'); if (contentDisposition) { const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (matches?.[1]) { fileName = decodeURIComponent(matches[1].replace(/['"]/g, '')); } } // 把响应转为Blob格式 const blob = await response.blob(); // 创建临时下载链接 const url = window.URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = fileName; document.body.appendChild(downloadLink); // 触发点击下载 downloadLink.click(); // 清理资源,避免内存泄漏 window.URL.revokeObjectURL(url); document.body.removeChild(downloadLink); } catch (error) { console.error('下载出错:', error); alert('文件下载失败,请稍后重试'); } } // 调用函数启动下载 downloadFileWithHeaders();
方案二:使用XMLHttpRequest(兼容旧浏览器)
function downloadFileWithHeadersXHR() { const downloadUrl = buildRequestUrl(); const xhr = new XMLHttpRequest(); xhr.open('GET', downloadUrl, true); // 添加自定义请求头 xhr.setRequestHeader('X-Custom-Token', 'your-auth-token'); xhr.setRequestHeader('X-User-Id', '12345'); // 指定响应类型为Blob xhr.responseType = 'blob'; xhr.onload = function() { if (xhr.status === 200) { // 提取文件名 let fileName = 'downloaded-file'; const contentDisposition = xhr.getResponseHeader('Content-Disposition'); if (contentDisposition) { const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (matches?.[1]) { fileName = decodeURIComponent(matches[1].replace(/['"]/g, '')); } } const blob = xhr.response; const url = window.URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = fileName; document.body.appendChild(downloadLink); downloadLink.click(); // 清理资源 window.URL.revokeObjectURL(url); document.body.removeChild(downloadLink); } else { console.error('请求失败,状态码:', xhr.status); alert('文件下载失败,请稍后重试'); } }; xhr.onerror = function() { console.error('网络请求出错'); alert('文件下载失败,请检查网络连接'); }; xhr.send(); } // 调用函数启动下载 downloadFileWithHeadersXHR();
关键注意事项:
- CORS跨域问题:如果请求是跨域的,后端必须配置允许携带自定义请求头(在响应头中添加
Access-Control-Allow-Headers: X-Custom-Token,X-User-Id),同时允许对应请求方法的跨域访问。 - 后端响应配置:后端需要正确返回
Content-Type(匹配文件类型,比如application/pdf、application/octet-stream),并且建议返回Content-Disposition头来指定文件名,这样前端能自动获取正确的文件名。 - 资源清理:一定要调用
window.URL.revokeObjectURL()释放Blob URL的资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者koryakinp
相关产品推荐
相关产品推荐

