接口返回内容使用response.json()报错问题

本文探讨了在发起GET请求并尝试解析响应为JSON格式时遇到的问题。具体表现为使用response.json()时出现的JSONDecodeError。通过调整请求头中的Accept-Encoding字段解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发起一个get请求时,使用response.json()打印响应结果一直报 : raise JSONDecodeError("Expecting value", s, err.value) from Nonejson.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)错误

报错代码:

studet_url = "https://你的域名/workbench_api/manager/list?_=1648455040100"

headers = {"Host": "你的域名",
           "Accept-Encoding": "gzip, deflate, br",  # 删除这一行就不会报错了
           "Connection": "keep-alive",
           "accept": "application/json; charset=utf-8",

           }
student = requests.get(url=studet_url, headers=headers, cookies=cookie)  
print(student.json()   # 这一句报错

后来发现原来的传递的请求头不对,将headers中的 "Accept-Encoding": "gzip, deflate, br"删除,再请求就不会报错了

问题原因:

大部分浏览器之所以添加:"Accept-Encoding" = "gzip,deflate"是因为浏览器对从服务器中返回的gzip压缩的网页,会自动解压缩。所以,浏览器在发起请求时添加 "Accept-Encoding": "gzip, deflate, br"代表可接受压缩后的数据以及对应的压缩格式。

而此代码中,如果也添加 "Accept-Encoding": "gzip, deflate, br",结果返回的就是压缩后的数据,没有解码,故无法使用response.json()。因为response.json()是将返回的json数据转为字典。

<think>好的,我现在需要解决用户的问题使用Axios发送请求时,接口正常返回数据,但前端却抛出错误。用户希望了解原因及解决方案。首先,我得回忆一下Axios的工作原理以及常见的错误处理机制。 首先,Axios在处理HTTP响应时,会根据状态码来决定是进入`then`还是`catch`。通常,状态码在2xx范围内会被视为成功,进入`then`,而其他状态码(如4xx或5xx)会触发`catch`块。但用户提到的是“正常返回数据却报错”,这可能意味着虽然服务器返回了数据,但状态码不在2xx范围内,导致Axios认为请求失败,从而进入错误处理。 接下来,我需要考虑可能的原因。根据用户提供的引用资料,特别是引用[3],当设置`responseType: 'blob'`时,即使后端返回错误信息(如JSON格式),Axios可能无法正确解析,因为期望的是Blob类型。这时候,如果直接尝试读取错误信息,可能会失败,导致无法获取正确的错误消息,进而触发异常。 另外,引用[4]提到Content-Type的问题,如果前后端的数据格式不一致,比如后端期望JSON但前端未正确设置请求头,可能导致415 Unsupported Media错误。虽然用户的问题不是直接关于415,但这也提示我需要检查请求配置是否正确,比如headers中的Content-Type是否与后端匹配。 再者,引用[2]中的415错误可能与旧版Axios的兼容性问题有关,但用户的问题可能不涉及版本,不过这也是一个可能的因素,需要确认使用的Axios版本是否存在已知问题。 现在,结合用户的问题,可能的原因包括: 1. 后端返回的状态码不在2xx范围内,导致Axios触发catch。 2.使用`responseType: 'blob'`时,错误信息被包裹在Blob中,前端未正确解析。 3. 后端返回的数据格式与前端期望的不一致,如返回JSON但前端解析为Blob。 4. 请求配置错误,如headers未正确设置,导致后端处理异常,返回错误状态码。 针对这些原因,解决方案可能包括: 1. 检查后端的HTTP状态码,确保在成功时返回2xx状态码。如果后端返回了如200,但前端仍报错,可能是其他问题。 2.使用`responseType: 'blob'`时,需要在错误处理中检查响应数据类型,如果是Blob,使用FileReader读取内容,如引用[3]所述。 3. 在Axios的拦截器中统一处理错误响应,特别是处理Blob类型的错误数据。 4. 验证请求的headers配置,确保Content-Type等设置正确,避免后端因无法解析请求数据而返回错误状态码,如引用[4]的建议。 此外,还需要考虑网络问题或跨域问题,但用户提到接口正常返回数据,所以可能排除网络问题,更多是数据处理的问题。 总结步骤: 1. 确认后端返回的状态码是否正确,是否在2xx范围内。 2. 如果使用了`responseType: 'blob'`,在错误处理中解析Blob数据。 3. 检查请求的headers配置,确保与后端要求一致。 4. 使用Axios拦截器统一处理错误响应,解析可能的Blob错误信息。 现在,我需要将这些思考整理成一个结构化的回答,包含原因分析和解决方案,并引用提供的参考资料。</think>### Axios请求正常返回数据却报错的原因及解决方案 #### **原因分析** 1. **HTTP状态码不符合2xx范围** Axios默认将2xx之外的状态码视为请求失败,自动触发`catch`分支。例如后端返回400/500等状态码时,即使响应体包含数据,仍会抛出错误[^1][^3]。 2. **Blob类型响应解析错误** 当设置`responseType: 'blob'`时(如文件下载场景),若后端返回错误信息(如JSON格式),前端直接解析Blob会失败,需手动读取内容。 3. **请求头配置错误** 未正确设置`Content-Type`或参数格式与后端不匹配(如未传JSON数据但未声明`application/json`),可能导致后端返回415等错误[^4]。 4. **旧版本Axios兼容性问题** 某些旧版本(如axios-0.18.0)可能存在HTTP状态码处理缺陷,需升级到新版本[^2]。 --- #### **解决方案** 1. **验证HTTP状态码范围** 确保后端在成功时返回2xx状态码(如200)。若无法修改后端,可在Axios拦截器中强制改写状态码: ```javascript axios.interceptors.response.use( response => response, error => { if (error.response.status === 400 && error.response.data) { return Promise.resolve(error.response); // 将错误转为成功 } return Promise.reject(error); } ); ``` 2. **解析Blob类型的错误信息** 在错误处理中判断响应数据类型,使用`FileReader`读取内容[^3]: ```javascript axios.get('/download', { responseType: 'blob' }) .catch(error => { if (error.response.data instanceof Blob) { const reader = new FileReader(); reader.onload = () => { const message = JSON.parse(reader.result).message; console.error('错误信息:', message); }; reader.readAsText(error.response.data); } }); ``` 3. **统一配置请求头** 明确设置`Content-Type`,确保与后端要求一致: ```javascript axios.post('/api', data, { headers: { 'Content-Type': 'application/json' } }); ``` 4. **升级Axios版本** 使用`npm update axios`或`yarn upgrade axios`更新至最新稳定版,避免旧版本缺陷[^2]。 --- #### **示例代码(完整拦截器实现)** ```javascript // 请求拦截器:统一添加Content-Type axios.interceptors.request.use(config => { config.headers['Content-Type'] = 'application/json'; return config; }); // 响应拦截器:处理Blob类型错误 axios.interceptors.response.use( response => response, error => { const res = error.response; if (res.data instanceof Blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { try { const data = JSON.parse(reader.result); if (res.status === 200) { resolve(res); // 正常数据 } else { console.error('错误信息:', data.message); reject(data.message); } } catch (e) { reject('解析失败'); } }; reader.readAsText(res.data); }); } return Promise.reject(error); } ); ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值