概念
axios 有一点好,可以在浏览器和node环境中使用。
在浏览器中使用 XHR
,在node中使用 http 发送请求。支持promise,可拦截可取消
当然了, axios
大火的一个因素也是因为 vue
官方文档指名道姓推荐了 axios
快速入门
const axios = require('axios')
// url get
axios.get('/user?v=2').then(res=>{}).catche().finally()
// get 带参数
axios.get('/user',{params:{ID:1}}).then().catch().then()
// async/await
async go(){
try{
const res = await axios.get('/user?v=2')
}catch(err){log(err)}
}
// post
axios.post('/user',{
a:2,b:1
}).then().catch()
// 执行多个请求
function a1(){return axios.get()}
function a2(){return axios.get}
axios.all([a1(),a2()]).then(axios.spread((acct,perms)=>{}))
api
axios(config)
axios({
method:'post',
url:'',
data:{
a:1
}
})
使用 stream 下载图片
axios({
method:'get',
url:'',
responseType:'stream'
}).then(res=>{
res.data.pipe(fs.createWriteStream(a.jpg))
})
axios(url[,config])
默认get
axios(url)
其他
- axios.request(config)
- axios.get(url[,config])
- axios.delete(url[,config])
- axios.head
创建一个实例
const i = axios.crate({
baseURL:'',
timeout:1000,
headers:{}
})
i.get()
返回的结构
var res = {
data:{},
status:200,
statusText:'OK',
headers:{},
config:{}
request:{}
}
默认情况下,axios把 Javascropt 转为json,如果要使用application/x-www-form-urlencoded
发送数据。
浏览器可以使用 qs库来编码
拦截器 interceptors
axios
可以对 request
和 response
进行拦截:
- 在发出请求时候可以修改 请求头,比如带上token
- 在收到相应时候可以对数据进行校验调整,比如判断 status 2xx 4xx 5xx
请看具体代码
// 请求拦截器
instance.interceptors.request.use((conf) => {
if (!conf.headers['Authorization']) {
conf.headers['Authorization'] = token();
}
return Promise.resolve(conf);
});
注意这里的 error: AxiosError
,并不是普通的 Error
对象
// 相应拦截器
instance.interceptors.response.use(
(res) => Promise.resolve(res),
async (error: AxiosError) => {}
)
// 也可以直接剥离我管的数据,只返回必要的data内容
instance.interceptors.response.use(
(res: AxiosResponse<CommonData<any>>):any => {
if (res.status >= 200 && res.status < 300) {
if (res.data.code === 0) {
return res.data.data
}
return res
// res = res.data
// if ((res.data as MyData).code === 0) {
// return res.data
// } else if (res.data.code) { }
}
}
)
这个经过封装的 error 对象,包含了本次失败的请求所包含的参数:
比如在我们的一个项目中,后端的现状是 请求接口只会是两种结果: status200 成功 , status401未授权。根据要求,我们需要在返回401时候请求接口更新token。(这种情况并不常见,但也是一种需求。)
这里就利用 error.config
对象,重新发出了请求。
后面讲源码时候会有进一步的补充。
结合 ts
ts中有一些类型比较常用:
AxiosInstance
对实例进行包装AxiosError
包装了axios的自定义错误类型AxiosResponse
包装了返回结果,我们一般只对 data 感兴趣AxiosPromise
对上面AxiosPromise
进行了Promise进行了包装,实际中更常用
源码
axios 基于 xhr实现,这部分细节可以参考我的博客 https://www.yuque.com/xinbao37/roadmap/js-web-api.md
- class Axios
- 自己new,然后到处实例
class Axios {
get(url){
let xhr = new XHR()
xhr.open('get', url, true)
xhr.send()
}
}
- 实现 then,返回的是 promise
- 包装 data status statusText
- 实现可选 get options,利用 constructor
深拷贝考虑 undefined,考虑function,常见类型问题不大
默认参数和自定义参数,要考虑 merge,注意覆盖和新增
mergeConfig
interceptors 拦截器,如果request有两个 use,会先执行下面的。