解决方案核心逻辑
检测响应内容类型
axios({ method: "post", url: base.apiUrl + `exportApi`, responseType: "arraybuffer", // 关键设置 data: json_, }).then(res => { // 检查响应内容类型 const contentType = res.headers['content-type']; if (res.status !== 200 || contentType.includes('application/json')) { // 处理错误响应 handleErrorResponse(res.data); } else { // 处理文件下载 handleFileDownload(res.data, res.headers); } })
错误响应处理(ArrayBuffer转字符串)
const handleErrorResponse = (arrayBuffer) => { // 将 ArrayBuffer 转换为字符串 const decoder = new TextDecoder('utf-8'); const errorText = decoder.decode(arrayBuffer); try { // 尝试解析为 JSON const errorObj = JSON.parse(errorText); ElMessage.warning(errorObj.message || '请求失败'); } catch { // 直接显示文本错误 ElMessage.warning(`错误: ${errorText}`); } }
文件下载处理
const handleFileDownload = (arrayBuffer, headers) => { // 创建 Blob 对象 // type 可直接设置文件格式 例如:type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" const blob = new Blob([arrayBuffer], { type: headers['content-type'] }); // 创建下载链接 const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; // 从 Content-Disposition 获取文件名 const contentDisposition = headers['content-disposition']; let fileName = 'download.bin'; // 自定义文件名称 if (contentDisposition) { const fileNameMatch = contentDisposition.match(/filename="?([^"]+)"?/); if (fileNameMatch && fileNameMatch[1]) { fileName = fileNameMatch[1]; } } a.download = fileName; document.body.appendChild(a); a.click(); // 清理 document.body.removeChild(a); window.URL.revokeObjectURL(url); }
处理特点
/* 统一处理响应:始终使用 responseType: "arraybuffer",确保能正确处理文件响应 智能错误检测:通过检查状态码和内容类型识别错误响应 错误消息提取:将 ArrayBuffer 转换为字符串并尝试解析 JSON 错误信息 自动文件名提取:从 Content-Disposition 头中提取文件名 */
09-08
9088
