三年前入职的时候还是一个只会使用Ajax和JqueryAjax的菜鸟,由于早期Jquery不支持大文件请求的问题,要么拆分文件,要么用XHR~今天总结一篇数据请求的进入今天的世界吧~~~
引言
前端的发展可以说是一个快速崛起的历程了,不断的进化,不断的出现新的Api,新的功能,前端这个领域真的是一个发展飞快的领域,你前一天刚学会XXX的的运用,后一天某某某就革新了一项新的技术,你在感叹学不动的同时,不得不继续学习。扯远了,回到我们今天的主题。。。
注意:以下篇幅较长,建议收藏了慢慢收看。在这里学到的肯定会对你有所帮助。
这只是一个区别介绍
「Ajax」
全称AsynchronousJavaScriptandXML(异步的JavaScript和XML)最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
「JqueryAjax」
是jQuery底层AJAX实现。简单易用的高层实现见$.get,$.post等。$.ajax()返回其创建的XMLHttpRequest对象。大多数情况下你无需直接操作该函数,除非你需要操作不常用的选项,以获得更多的灵活性。jQueryajax-ajax()方法
「Axios」
「Fetch」
Fetch提供了对Request和Response(以及其他与网络请求有关的)对象的通用定义。使之今后可以被使用到更多地应用场景中:无论是serviceworkers、CacheAPI、又或者是其他处理请求和响应的方式,甚至是任何一种需要你自己在程序中生成响应的方式。`Fetch`号称是AJAX的替代品,是在ES6出现的,使用了ES6中的[Promise]对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQueryajax。注意,一定记住fetch不是ajax的进一步封装,而是原生js。Fetch函数就是原生js。
进入细谈环节
详细的描述一下Ajax,jQueryajax,axios和fetch区别,让我们继续往下研究。
01
Ajax=异步JavaScript和XML
02
Ajax是一种用于创建快速动态网页的技术
通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
AJAX工作原理
Ajax
[XMLHttpRequest]让发送一个HTTP请求变得非常容易。你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求。当传输完毕后,结果的[HTTP状态]以及返回的响应内容也可以从请求对象中获取。简单的来叙述一下这个过程,往下看:
1-1
请求类型
通过XMLHttpRequest生成的请求可以有两种方式来获取数据,异步模式或同步模式。请求的类型是由这个XMLHttpRequest对象的open()方法的第三个参数async的值决定的。如果该参数的值为false,则该XMLHttpRequest请求以同步模式进行,否则该过程将以异步模式完成。
注意:由于对用户体验的糟糕效果,从Gecko30.0(Firefox30.0/Thunderbird30.0/SeaMonkey2.27)版本开始,在主线程上的同步请求已经被弃用。
1-2
处理响应
W3C规范定义了XMLHttpRequest对象的几种类型的响应属性。这些属性告诉客户端关于XMLHttpRequest返回状态的重要信息。一些处理非文本返回类型的用例可能包含一些下面章节描述的操作和分析。
分析并操作responseXML属性
如果你使用XMLHttpRequest来获得一个远程的XML文档的内容,responseXML属性将会是一个由XML文档解析而来的DOM对象,这很难被操作和分析。这里有五种主要的分析XML文档的方式:
●1.使用XPath定位到文档的指定部分。
●2.手工的解析和序列化XML为字符串或对象。
●3.使用XMLSerializer把DOM树序列化成字符串或文件。
●4.如果你预先知道XML文档的内容,你可以使用RegExp。如果你用RegExp扫描时受到换行符的影响,你也许想要删除所有的换行符。然而,这种方法是"最后手段",因为如果XML代码发生轻微变化,该方法将可能失败。
解析和操作包含HTML文档的responseText属性
如果使用XMLHttpRequest从远端获取一个HTML页面,则所有HTML标记会以字符串的形式存放在responseText属性里,这样就使得操作和解析这些标记变得困难。解析这些HTML标记主要有三种方式:
●XMLHttpRequestresponseXML属性。
●将内容通过fragment.body.innerHTML注入到一个文档片段中,并遍历DOM中的片段。
●如果你预先知道HTML文档的内容,你可以使用RegExp。如果你用RegExp扫描时受到换行符的影响,你也许想要删除所有的换行符。然而,这种方法是"最后手段",因为如果HTML代码发生轻微变化,该方法将可能失败。
1-3
处理二进制数据
尽管XMLHttpRequest一般用来发送和接收文本数据,但其实也可以发送和接受二进制内容。有许多经过良好测试的方法来强制使用XMLHttpRequest发送二进制数据。利用XMLHttpRequest.overrideMimeType()方法是一个解决方案,虽然它并不是一个标准方法。
在XMLHttpRequestLevel2规范中新加入了responseType属性,使得发送和接收二进制数据变得更加容易。
1-4
监测进度
XMLHttpRequest提供了各种在请求被处理期间发生的事件以供监听。这包括定期进度通知、错误通知,等等。
支持DOM的progress事件监测之于XMLHttpRequest传输,遵循WebAPI进度事件规范:这些事件实现了ProgressEvent接口。
1-5
提交表单和上传文件
XMLHttpRequest的实例有两种方式提交表单:
1
使用Ajax
2
使用FormDataAPI
使用FormDataAPI是最简单最快捷的,但是缺点是被收集的数据无法使用JSON.stringify()转换为一个JSON字符串。第一种方式反而是最复杂的但也是最灵活和最强大。
请求方式这里不做太多赘述,一个传送门,有兴趣的小伙伴可以自己去查阅一下。
JqueryAjax
传统Ajax指的是XMLHttpRequest(XHR),最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。JqueryAjax的出现是对原生XHR的封装,除此以外还增添了对JSONP的支持,JqueryAjax经过多年的更新维护,真的已经是非常的方便了,但是随着react,vue,angular新一代框架的兴起,以及ES规范的完善,更多API的更新,它逐渐暴露了自己的不足:
★本身是针对MVC的编程,不符合现在前端MVVM的浪潮、配置和调用方式非常混乱,而且基于事件的异步模型不友好
★基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
★JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
默认情况下,Ajax请求使用GET方法。如果要使用POST方法,可以设定type参数值。这个选项也会影响data选项中的内容如何发送到服务器。
下面的表格列出了jQueryAJAX方法:
执行异步AJAX请求对于JqueryAjax来说我是特别的喜欢。
03
Axios
先来看看官网的案例:
执行GET请求
执行POST请求
执行多个并发请求
Vue2.0之后,尤雨溪推荐大家用axios替换JQueryajax,未来App的趋势是轻量化和细化,能解决问题的应用就是好应用,想必让Axios进入了很多人的目光中。Axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,可以用在浏览器和node.js中,符合最新的ES规范,从它的官网上可以看到它有以下几条特性:
从浏览器中创建XMLHttpRequests。
支持PromiseAPI。
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换JSON数据
客户端支持防御XSRF
XSRF(CrossSiteRequestForgery,跨站域请求伪造)也称XSRF,是一种网络的攻击方式,它在2007年曾被列为互联网20大安全隐患之一。其他安全隐患,比如SQL脚本注入,跨站域脚本攻击等在近年来已经逐渐为众人熟知,很多网站也都针对他们进行了防御。然而,对于大多数人来说,CSRF却依然是一个陌生的概念。即便是大名鼎鼎的Gmail,在2007年底也存在着CSRF漏洞,从而被黑客攻击而使Gmail的用户造成巨大的损失。客户端支持防御XSRF,是怎么做到的呢,就是让你的每个请求都带一个从cookie中拿到的key,根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
Axios既提供了并发的封装,体积也较小,也没有下文会提到的fetch的各种问题,当之无愧是现在最应该选用的请求的方式。
04
Fetch
Fetch提供了对Request和Response(以及其他与网络请求有关的)对象的通用定义。Fetch是一个现代的概念,等同于XMLHttpRequest。它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。
FetchAPI提供了一个JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
请注意,fetch规范与jQuery.ajax()主要有两种方式的不同,牢记:
★当接收到一个代表错误的HTTP状态码时,从fetch()返回的Promise不会被标记为reject,即使该HTTP响应的状态码是404或500。相反,它会将Promise状态标记为resolve(但是会将resolve的返回值的ok属性设置为false),仅当网络故障时或请求被阻止时,才会标记为reject。
★默认情况下,fetch不会从服务端发送或接收任何cookies,如果站点依赖于用户session,则会导致未经认证的请求(要发送cookies,必须设置credentials选项)。自从2017年8月25日后,默认的credentials政策变更为same-originFirefox也在61.0b13中改变默认值
一个基本的fetch请求设置起来很简单。看看下面的代码:
这里我们通过网络获取一个JSON文件并将其打印到控制台。最简单的用法是只提供一个参数用来指明想fetch()到的资源路径,然后返回一个包含响应结果的promise(一个Response对象)。
当然它只是一个HTTP响应,而不是真的JSON。为了获取JSON的内容,我们需要使用json()方法(在Bodymixin中定义,被Request和Response对象实现)。
fetch()接受第二个可选参数,一个可以控制不同配置的init对象:
fetch的优点:
语法简洁,更加语义化
基于标准Promise实现,支持async/await。
3
同构方便,使用isomorphic-fetch
4
更加底层,提供的API丰富(request,response)
5
脱离了XHR,是ES规范里新的实现方式
fetch在前端的应用上有一项xhr怎么也比不上的能力:跨域的处理
我们都知道因为同源策略的问题,浏览器的请求是可能随便跨域的——一定要有跨域头或者借助JSONP,但是,fetch中可以设置mode为"no-cors"(不跨域),如下所示:
这样之后我们会得到一个type为“opaque”的返回。需要指出的是,这个请求是真正抵达过后台的,所以我们可以使用这种方法来进行信息上报,在我们之前的image.src方法中多出了一种选择,另外,我们在network中可以看到这个请求后台设置跨域头之后的实际返回,有助于我们提前调试接口(当然,通过chrome插件我们也可以做的到)。