如何处理HttpClient设置responseType为blob时的请求错误?
处理HttpClient请求Blob时的错误响应解析问题
我完全懂你的困扰——当你把responseType设为blob后,不管请求成功还是失败,响应体都会被当成Blob处理,错误信息根本没法直接读取。别慌,这里有几个实用的解决方案,帮你搞定这个问题:
方案一:在错误回调中手动解析Blob
错误响应的error.error其实是Blob对象,我们可以用FileReader把它转换成文本,再根据后端返回的格式(JSON或纯文本)进一步处理:
this.httpClient.get('http://m502126:3000/reports/perdate', { observe: 'body', responseType: 'blob', params: new HttpParams() .set('START_DATE', startDate) .set('END_DATE', endDate) .set('MIXER', mixer) .set('ATTACH', 'true') }).subscribe( data => { console.log(data); }, error => { // 检查是否是Blob类型的错误响应 if (error.error instanceof Blob) { const reader = new FileReader(); // 读取完成后处理结果 reader.onload = () => { const errorContent = reader.result as string; try { // 如果后端返回的是JSON格式错误,解析成对象 const errorObj = JSON.parse(errorContent); console.error('解析后的错误详情:', errorObj); // 这里可以添加用户提示逻辑,比如errorObj.message } catch (e) { // 如果是纯文本错误,直接使用 console.error('错误信息:', errorContent); } }; // 以文本形式读取Blob reader.readAsText(error.error); } else { // 非Blob类型的错误,直接处理 console.error(error); } } );
方案二:观察完整响应对象,提前判断状态
把observe设为response,这样你能拿到完整的HTTP响应对象,先通过状态码判断请求是否成功,再针对性处理响应体:
this.httpClient.get('http://m502126:3000/reports/perdate', { observe: 'response', // 获取完整响应对象 responseType: 'blob', params: new HttpParams() .set('START_DATE', startDate) .set('END_DATE', endDate) .set('MIXER', mixer) .set('ATTACH', 'true') }).subscribe({ next: (response) => { // 成功时,response.body就是Blob console.log('返回的Blob数据:', response.body); }, error: (error) => { if (error.error instanceof Blob) { // 复用方案一的解析逻辑 const reader = new FileReader(); reader.onload = () => { try { const errorData = JSON.parse(reader.result as string); console.error('错误详情:', errorData); } catch (e) { console.error('错误文本:', reader.result); } }; reader.readAsText(error.error); } else { console.error(error); } } });
方案三:封装解析逻辑为工具函数(可选)
如果多个地方都需要处理这种情况,可以把Blob解析逻辑封装成工具函数,让代码更简洁:
// 工具函数:解析Blob错误为文本或JSON const parseBlobError = (blob: Blob): Promise<string | object> => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { try { resolve(JSON.parse(reader.result as string)); } catch (e) { resolve(reader.result as string); } }; reader.onerror = () => reject(reader.error); reader.readAsText(blob); }); }; // 使用示例 this.httpClient.get(/* ... */).subscribe({ // ... error: async (error) => { if (error.error instanceof Blob) { const errorInfo = await parseBlobError(error.error); console.error('处理后的错误信息:', errorInfo); // 这里可以添加UI提示等逻辑 } } });
额外提示
如果后端可以配合调整,建议让后端在返回错误时,同时设置正确的Content-Type(比如application/json),不过这个需要后端团队配合,不是前端能单独控制的,所以优先用前面的前端方案。
内容的提问来源于stack exchange,提问作者vertika
相关产品推荐
相关产品推荐

