基本用法
GET
两者都是基于Promise,所以可以使用.then 也可以使用async await。
fetch需要手动对相应内容进行转换,axios会根据响应头类型,进行自动转换。所以axios的代码更加简洁。
axios.get("http://localhost:8000/api/...").then((res) => {console.log(res.data);});const res = await axios.get("http://localhost:8000/api/...");console.log(res.data)fetch("http://localhost:8000/api/...").then((res)=>res.text()).then(console.log)const res = await fetch("http://localhost:8000/api/...");const data = await res.text();console.log(data)
POST(json+header)
axios的post会自动设置请求的content-type,fetch需要手动设置。除此之外,fetch的json参数需要序列化为字符串。
const params = {name:"zhangsan"};const headers = {"token":"..."};axios.post(url,params,{headers})const params = {name:"zhangsan"};const headers = {"token":"...","Content-Type":"application/json"};fetch(url,{method:"POST",body:JSON.stringify(params),headers})
POST(formdata)
对于表单请求,两者都能通过formdata参数指定content-type。
axios提供了直接用于表单请求的方法,可以直接将表单的文件内容作为参数,在某些场景下更方便一些。
const form = new FormData();form.append("name","zhangsan");form.append("file",file);axios.post(url,form)axios.postForm(url,{name:"zhangsan",_file:file})const form = new FormData();form.append("name","zhangsan");form.append("file",file);fetch(url,{method:"POST",body:form})
数据流
axios在浏览器环境,并不支持string类型,所以并不能直接处理数据流。如果请求二进制数据,只能通过所有的内容传输完成后,在处理。
fetch可以通过res的body属性实现数据流的处理。
axios.get(url,{responseType:"arraybuffer"}).then((res)=>{// 传输完成后处理res.data})fetch(url).then((res)=>{const reader = res.body.getReader();})
中止请求
axios和fetch都可以通过abort方法来中断请求。
const controller = new AbortController();axios.get(url,{signal:controllerq.signal})controller.abort();fetch(url,{signal:controller.signal})controller.abort();
请求超时
axios可以设置超时参数,fetch可以通过abortSignal方法来设置超时,不过这个方法比较新,一些老的浏览器可能不兼容,可以通过abortControl来处理。
axios.get(url,{timeout:5000}).catch((err)=>{if(err.code === "ECONNABORTED"){// 超时处理}})fetch(url,{signal: AbortSignal.timeout(5000)}).catch((err)=>{if(err.name === "TimeoutError"){// 超时处理}})
进度监控
axios提供了上传/下载进度回调。
fetch没有直接提供进度的回调,可以通过数据流的形式,获取单体下载的进度。对于上传文件,fetch还没办法获取进度。
axios.post(url,formData,{onUploadProgress:(e)=>{const percent = Math.round((e.loaded * 100) / e.total);console.log(`上传进度:${percent}%`)}})axios.get(url,{responseType:"arraybuffer",onDownloadProgress:(e)=>{const percent = Math.round((e.loaded * 100) / e.total);console.log(`下载进度:${percent}%`)}})const response = await fetch(url);const reader = response.body.getReader();const total = +response.headers.get("Content-Length");let received = 0; while(true){const {done,value} = await reader.read();if(done){break;}received += value.length;console.log(`下载进度:${Math.round((received * 100) / total)}%`)}
兼容性
axios支持所有的主流浏览器
基于XMLHttpRequest,向后兼容表现更好。
非浏览器自带,需要安装,占用一些体积,体积敏感需要考虑。
fetch支持所有主流浏览器
相对较新的接口,一些老版本浏览器和IE浏览器可能不支持,虽然可以通过第三方库兼容,但是会失去部分特性。
浏览器自带功能,无需安装,不占体积。
总结
axios和fetch都是好用的http通信方式,绝大部分情况下,axios和fetch都可以满足,只有少数情况下,比如说
相应数据流处理,axios无法满足,需要使用fetch
上传进度监控,fetch无法满足,需要使用axios或者XMLHttpRequest
axios和fetch并不是非要二选一,实际开发中应该根据情况灵活选择,综合运用。