基于CORS与jQuery AJAX的文件流式传输Blob错误处理问询
问题:CORS流式传输Blob时无法读取自定义错误响应头
我在JavaScript中通过CORS从服务器流式传输文件到本地保存,遇到了错误处理的难题。由于响应类型被强制设置为Blob,无法用JSON返回错误信息,于是尝试在服务器端设置自定义响应头传递错误内容,但前端调用jqXHR.getResponseHeader('X-Error-Message')时控制台输出null,确认服务器已经成功设置了该响应头。
服务器1(前端JavaScript代码)
jQuery.ajax({ xhr: () => { let xhr = new window.XMLHttpRequest(); xhr.addEventListener("progress", evt => { if (evt.lengthComputable) { let percentComplete = evt.loaded / evt.total; // TODO 发送进度到页面的动画进度条 } }, false); return xhr; }, type: "GET", url: link, processData: false, contentType: false, cache: false, timeout: 180000, xhrFields: { responseType: 'blob' }, success: (data, status, jqXHR) => { let disposition = jqXHR.getResponseHeader('Content-Disposition'); let filename = ''; console.log(disposition); if (disposition && disposition.indexOf('attachment') !== -1) { let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; let matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); saveAs(data, filename); } else { errorCallback(jqXHR, 'error', 'Invalid Response Header'); } }, error: function(jqXHR, textStatus, errorThrown) { // 修正:读取正确的自定义错误头字段 let errorMessage = jqXHR.getResponseHeader('X-Error-Message'); console.log(errorMessage); } }); function saveAs(data, filename) { let rawdata = new Blob([data], { type: "application/octet-stream" }); if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(rawdata, filename); } else { let menulink = window.document.createElement("a"); menulink.href = window.URL.createObjectURL(rawdata); menulink.download = filename; document.body.appendChild(menulink); menulink.click(); document.body.removeChild(menulink); } }
服务器2(后端PHP代码)
header('Access-Control-Allow-Origin: *'); // 关键添加:暴露自定义响应头给前端 header('Access-Control-Expose-Headers: X-Error-Message'); // 设置自定义错误信息头 header('X-Error-Message: Second Server says this is an error example'); http_response_code(500); die();
解决方案说明
后端核心修正:
在CORS请求场景下,浏览器默认只允许前端读取少数安全响应头(如Content-Type、Cache-Control等)。自定义响应头必须通过Access-Control-Expose-Headers显式声明,否则前端无法通过getResponseHeader获取到对应值。前端修正:
原代码错误读取了X-Powered-By头,需要改为读取自定义的X-Error-Message头字段。
完成这两处修改后,前端就能正常获取到服务器返回的自定义错误信息了。
内容的提问来源于stack exchange,提问作者matead
相关产品推荐
相关产品推荐

