原生xhr对象
现代浏览器,最开始与服务器交换数据,都是通过XMLHttpRequest对象。它可以使用JSON、XML、HTML和text文本等格式发送和接收数据。
好处:
不重新加载页面的情况下更新网页
在页面已加载后从服务器请求/接收数据
在后台向服务器发送数据。
缺点:
使用起来也比较繁琐,需要设置很多值。
早期的IE浏览器有自己的内置对象,这样需要写兼容代码判断是否为XMLHttpRequest对象。
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)
}
}
jQuery里的$.ajax
为了方便操作dom并避免一些浏览器兼容问题,产生了jquery,
它里面的AJAX请求也兼容了不同的浏览器,可以直接使用.get、.pist。它就是对XMLHttpRequest对象的一层封装
优点:
对原生XHR的封装,做了兼容处理,简化了使用。
增加了对JSONP的支持,可以简单处理部分跨域。
缺点:
如果有多个请求,并且有依赖关系的话,容易形成回调地狱。
本身是针对MVC的编程,不符合现在前端MVVM的浪潮。
ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。
axios
Axios是一个基于promise的HTTP库,可以用在浏览器和 node.js 中。它本质也是对原生XMLHttpRequest的封装,只不过它是Promise的实现版本,符合最新的ES规范。
优点:
从浏览器中创建XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防止CSPRF
提供了一些并发请求的接口
缺点:
只持现代代浏览器.
axios({
method: 'post',
url: '/userlist/all',
data: {
id: '1',
page:1,
limit: 20
}
})
.then(res => console.log(res))
.catch(err => console.log(err))
fetch
Fetch API提供了一个 JavaScript 接口,用于访问和操作HTTP管道的部分,例如请求和响应。它还提供了一个全局fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
fetch是低层次的API,代替XHR,可以轻松处理各种格式,非文本化格式。可以很容易的被其他技术使用,例如Service Workers。但是想要很好的使用fetch,需要做一些封装处理。
fetch('http://acccess/.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
//在配置中,添加mode: 'no-cors'就可以跨域了
fetch('/users.json', {
method: 'post',
mode: 'no-cors',
data: {}
}).then(function() { /* handle response */ });
优点:
语法简介,更加语义化
基于标准promise实现,支持async/await
更加底层,提供的API丰富(request,response)
脱离了XHR,是Es规范里新的实现方式
问题:
支队网络请求报错,也就是说只有网络错误这些导致请求不能完成时他才会调用reject,而对400,500这种错误它并不会reject
默认不会带cookie,需要添加配置项:fetch(url,{credentials:'include'})
不支持abort,不支持超时控制,使用setTimeout及promise.reject的实现的超时控制不能阻止请求过程继续在后台运行,会造成流量的浪费
fetch没办法原生检测请求的进度,XHR可以
1 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
2 认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。