本文是“axios源码系列”第二篇。上文我们介绍了 axios 中是如何实现取消请求 的,本文我将介绍另一个话题:axios 是 JSON 响应优先的。
那为什么这么说呢?我们能从 2 个方面的表现进行阐述。
表现一:默认请求头
你可能没有注意到,每个 axios 请求默认会有 2 个请求头配置,位于 lib/defaults/index.js。
1 | js复制代码// /v1.6.8/lib/defaults/index.js#L144 |
- 首先,明确告知服务器,我能接受 JSON 数据响应。
- 其次,不发送 Content-Type 头信息。
这块配置会在请求发出前,与用户传入的 config.headers 进行合并。
1 | js复制代码// /v1.6.8/lib/core/Axios.js#L72 |
接着扁平化,将 config.headers 处理成 AxiosHeaders 实例对象。
1 | js复制代码// /v1.6.8/lib/core/Axios.js#L100-L113 |
AxiosHeaders 类似于标准 Headers API,提供了各种操作头信息的方法,比如 get()、set()、concat() 等。
看下最终请求头效果。
这就是 axios 是 JSON 响应优先的第一个表现。
表现二:响应数据处理
不过重要的还是第二个表现,即在处理响应数据的时候。
我们都知道,我们可以为 axios 请求指定 responseType 配置项。以下面代码为例:
1 | js复制代码axios.get('https://httpstat.us/200', { |
这里我们告知 axios,响应数据是 JSON 格式的,需要处理成 JSON 对象给我们。
但这个配置项是可选的,因为 axios 默认就会把响应数据看做 JSON 格式处理。
这块逻辑跟另一个配置项 transformResponse 有关。
如果你没有自定义 transformResponse 这个配置项,那么它的默认逻辑如下。
1 | js复制代码// /blob/v1.6.8/lib/defaults/index.js#L99 |
transformResponse 配置项接收请求返回的响应数据 data,决定最终返回的数据类型。而 data 的来源如下(以浏览器端实现为例)。
1 | js复制代码// /v1.6.8/lib/adapters/xhr.js#L100 |
这里的 responseType,是从传入用户的 config 里获取的。
1 | js复制代码// /v1.6.8/lib/adapters/xhr.js#L52 |
观察就能知道:当传入的 config 没有包含 responseType,或 responseType 值为 ‘text’ 或 ‘json’ 时,data 即 request.responseText,也就是一个字符串。
回到刚才的逻辑。
1 | js复制代码transformResponse: [function transformResponse(data) { |
如果 responseType 没有设置,或者 responseType 被设置成 ‘json’。那么就以 JSON.parse(data) 方式处理并返回。
看,这里的 data 属性就是一个 JS 对象了。
如果把 responseType 被设置成 ‘text’,返回的就是没经过任何处理的字符串了。
1 | js复制代码axios.get('https://httpstat.us/200', { |
效果如下。
这就是 axios 是 JSON 响应优先的第二个表现,也是直接原因。
总结
本文带大家了解了 axios 的另一个特性,它是 JSON 响应优先的。也就是说,JSON 响应在 axios 中是“一等公民”。
这并不难理解,因为目前几乎所有前端项目都在使用 JSON 格式返回响应数据。因此,这种默认设置也减少了一些样板代码的编写,提升了开发体验。
本文转载自: 掘金