ajax和axios、fetch的区别
https://www.jianshu.com/p/8bc48f8fde75 区别
https://www.jianshu.com/p/7c55f930d363 fetch详解
ajax和axios、fetch的区别
1.jQuery ajax
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持。经过多年的更新维护,真的已经是非常的方便了,优点无需多言;如果是硬要举出几个缺点,那可能只有:
1.本身是针对MVC的编程,不符合现在前端MVVM的浪潮
2.基于原生的XHR开发,XHR本身的架构不清晰。
3.JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
4.不符合关注分离(Separation of Concerns)的原则
5.配置和调用方式非常混乱,而且基于事件的异步模型不友好。
PS:MVVM(Model-View-ViewModel), 源自于经典的 Model–View–Controller(MVC)模式。MVVM 的出现促进了 GUI 前端开发与后端业务逻辑的分离,极大地提高了前端开发效率。MVVM 的核心是 ViewModel 层,它就像是一个中转站(value converter),负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的最重要一环。
如下图所示:
2.axios
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Vue2.0之后,尤雨溪推荐大家用axios替换JQuery ajax,想必让axios进入了很多人的目光中。
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征:
1.从浏览器中创建 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止CSRF
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js 创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据
PS:防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
3.fetch
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优点:
1.符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
2.更好更方便的写法
坦白说,上面的理由对我来说完全没有什么说服力,因为不管是Jquery还是Axios都已经帮我们把xhr封装的足够好,使用起来也足够方便,为什么我们还要花费大力气去学习fetch?
我认为fetch的优势主要优势就是:
1. 语法简洁,更加语义化
2. 基于标准 Promise 实现,支持 async/await
3. 同构方便,使用 [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch)
4.更加底层,提供的API丰富(request, response)
5.脱离了XHR,是ES规范里新的实现方式
最近在使用fetch的时候,也遇到了不少的问题:
fetch是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。
例如:
1)fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
2)fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
3)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
4)fetch没有办法原生监测请求的进度,而XHR可以
总结:axios既提供了并发的封装,也没有fetch的各种问题,而且体积也较小,当之无愧现在最应该选用的请求的方式。
fetch详解部分:
fetch请求出来了一段时间,短暂的在项目中使用过.这次好好学习汇总一下.
第一: fetch的使用
https://github.com/github/fetch 这个是fetch的github 上面给出了fetch用法.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch 这个是fetch的mdn文档,更加的详细.
查看两份文档的时候,github上面没有设置headers 而在 mdn上有.一开始我也很迷茫,最后我读到了一句话
因为fetch 会自己的匹配数据类型设置 content type, 所以发送json 或者formdata 等其他数据类型的时候,不需要你手动设置.
so intelligently.
所以在大部分使用的的情况下,直接使用就行. 和传统的ajax比起来,fetch 使用起来更加方便,少了繁琐的配置,又是基于promise,开发者专注于业务就行.
第二: fetch 的缺点
1.兼容性,fetch的兼容性并不太好,ie 和 safari 都不支持
在移动端和pc端 兼容性不好因为 返回的reponse body 是readable stream 不支持.
解决方案: 使用第三方库 whatwg-fetch, 如果同构在node端使用isomorphic-fetch.
2.fetch 请求默认不带cookie
前端请求的时候都会设计到token 权限验证,很多时候是存在cookie里面的.fetch里面又一个参数credentials设计cookie
credentials 有三个值:
omit: 默认值,忽略cookie的发送
same-origin: 表示cookie只能同域发送,不能跨域发送
include: cookie既可以同域发送,也可以跨域发送 ( 推荐使用)
推荐使用include.
3.fetch 跨域问题
fetch跨域也有对应的参数设置mode
same-origin:该模式是不允许跨域的,它需要遵守同源策略,否则浏览器会返回一个error告知不能跨域;其对应的response type为basic。
cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求不需要后端额外的CORS支持;其对应的response type为cors。
no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;这也是fetch的特殊跨域请求方式;其对应的response type为opaque。
4.fetch 返回400 500 问题
当一个请求发送完成,服务返回状态码,fetch 不会reject这个response,仍然resolve,但是 response.ok 会设置成false.很多时候我们会二次封装fetch reject error.
5 fetch 无法 abort 请求 和timeout
目前fetch 没有传统ajax 的abort 方法,还在草案之中
给fetch内部的promise添加一个abort方法--实际就是reject一个error.
使用promise 的race, 因为promise 里面的resolve 和 reject 只能执行一次, 利用race reject 一个error.
上面的abort 并没有真正的abort 此次请求,只是通过promise promise reject 一个error而已.我在翻阅fetch的源码的时候发现了这个
在配置中确实又一个signal 参数可以abort 请求,发现是基于AbortController,但是这个是一个实验中属性,基本不能使用.
以上是我对fetch粗浅的总结,有不足的地方欢迎指出.
作者:eveah
链接:https://www.jianshu.com/p/7c55f930d363
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。