1. XMLHttpRequest对象
现代浏览器,最开始与服务器交换数据,都是通过XMLHttpRequest对象。它可以使用JSON、XML、HTML和text文本等格式发送和接收数据
好处
- 能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据
不足
- 使用起来也比较繁琐,需要设置很多值。
- 早期的IE浏览器有自己的实现,这样需要写兼容代码。
if (window.XMLHttpRequest) { // model browser
xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('POST', url, true)
xhr.send(data)
xhr.onreadystatechange = function () {
try {
// TODO 处理响应
if (xhr.readyState === XMLHttpRequest.DONE) {
// XMLHttpRequest.DONE 对应值是 4
// Everything is good, the response was received.
if (xhr.status === 200) {
// Perfect!
} else {
// There was a problem with the request.
// For example, the response may hava a 404 (Not Found)
// or 500 (Internal Server Error) response code.
}
} else {
// Not ready yet
}
} catch (e) {
// 通信错误的事件中(例如服务器宕机)
alert('Caught Exception: ' + e.description)
}
}
2. jQuery Ajax
是对原生XHR的封装,为了达到我们跨越的目的,增添了对JSONP的支持。相当成熟和好用,但是随着React,Vue等新一代框架的兴起,以及ES规范的完善,更多API的更新,我们只需要使用Ajax却要引入庞大的jQuery,于是有了fetch。Ajax也逐渐暴露了自己的不足。
- 针对MVC的编程设计,不符合现在前端MVVM的趋势
- 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
- JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
- 虽然axios不支持jsonp,但是可以通过引入jsonp模块来解决
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
fetch
ajax的替代品,它的API是基于Promise设计的,是在ES6出现的。
fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch(url).then(response = > {
if (response.ok) {
response.json()
}
}).then(data = > console.log(data)).
catch (err = > console.log(err))
//搭配async/await使用,会让我们的一部代码更优雅
async function test() {
let response = await fetch(url);
let data = await response.json();
console.log(data)
}
//看起来和同步代码一样,但是async/await 是ES7 的API,还需要我们使用babel进行转译成ES5代码
优点
- 跨域处理(mode为"no-cors")
fetch('/testPost', { method: 'post', mode: 'no-cors', data: {} }).then(function() {});
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 更加底层,提供的API丰富(request, response)
- 脱离了XHR,是ES规范里新的实现方式
目前存在的问题
- fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。( 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject)
- fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
axios(推荐)
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'liu',
lastName: 'weiqin'
}
})
.then(res => console.log(res))
.catch(err => console.log(err))
优点
- 从浏览器中创建XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise 所有API
- 客户端支持防止CSRF (防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略)
- 自动转换JSON数据
不足
- 只持现代代浏览器
网友评论