前言
随着前后端分离模式的流行,在项目开发过程中必不可少的一项就是与后台进行交互,从早期的Ajax(XMLHttpRequest), 到现在ES6中的Fetch Api,都是为了解决异步数据请求的问题,可以说Fetch的出现就是为了以一种更标准的方式来替代XMLHttpRequest,下面就来具体分析下他们存在哪些区别?
网上很多资料说fetch是对XMLHttpRequest的封装,这应该是有问题的,实际上fetch是对http接口的封装,两者没有任何的关系,它是一个新的api
相同点
- 都是浏览器提供的功能,可以发送http网络请求,接收服务器返回的数据
- 在浏览器中都存在跨域问题
区别点
核心实现
XMLHttpRequets和fetch虽然功能类似,但是在核心实现上是不一样的
-
fetch底层是对http接口的封装
-
XMLHttpRequets基于回调函数,而Fetch是基于promise的设计
代码写法
最直观的就是写法有很大的不同,比如请求一个url接口地址
XMLHttpRequest写法
const url = 'http://xxx.com.cn'
const xmlHttp = new XMLHttpRequest()
xmlHttp.open('get', url, true)
xmlHttp.onreadystatechange = () => {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
console.log(xmlHttp.response)
}
}
xmlHttp.onerror = () => {
console.log('error')
}
xmlHttp.send()
fetch写法
const url = 'http://xxx.com.cn'
fetch(url).then((response) => {
return response.json()
}).then(data => {
console.log(data)
}).catch(err => {
console.log(err)
})
可以看到fetch相对XMLHttpRequest来说在实现上更加的方便和简洁
兼容性
XMLHttpRequets兼容性非常好,基本是所有的浏览器都支持
fetch由于是新的api,所以兼容性比XMLHttpRequets要差点,但是主流的浏览器基本都已经支持了
跨域设置
请求接口如有存在跨域并且要传递cookie时,需要进行配置
XMLHttpRequest
const xmlHttp = new XMLHttpRequest()
....
xhr.withCredentials = true // 配置跨域传递cookie
....
fetch
fetch(url, {
credentials: 'include', // 配置跨域传递cookie
mode: 'cors' // 以cors的形式配置跨域
})
进度读取
XMLHttpRequest
可以对下载和上传的进度进行监听, 监听的事件需要写在open
方法之前
# 下载数据监听
const xhr = new XMLHttpRequest()
xhr.addEventListener('progress', (e) => {
}, false)
xhr.open()
xhr.send()
# 上传数据监听
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (e) => {
}, false)
....
fetch
无法监听到进度状态
超时中断请求
XMLHttpRequest
在请求中可以设置超时属性,可以通过abort()中断当前请求
const xhr = new XMLHttpRequest()
xhr.open('get', 'http://xxx.com/api', true)
xhr.timeout = 30000
xhr.onload = () => {
// 请求完成 todo
}
xhr.ontimeout = (e) => {
// 请求超时todo
}
xhr.send()
fetch
fetch没有超时属性和终止当前请求的方法,需要手动的实现