你不需要jQuery(三) 新AJAX方法fetch()
XMLHttpRequest来完成ajax有些老而过时了。
fetch()能让我们完成类似XMLHttpRequest(XHR)提供的ajax功能。它们之间的主要区别是,FetchAPI使用了Promises,它让接口更简单、简洁,避免了回调的复杂性,省去了使用复杂的XMLHttpRequestAPI。
如果你之前未使用过Promises,你应该先看看《JavaScriptPromises用法》这篇文章。
一、基本Fetch用法
让我们先用一个例子来比较一下使用XMLHttpRequest和使用fetch之间的不同。我们要请求一个URL,获取JSON格式的返回结果。
XMLHttpRequest
一个XMLHttpRequest请求需要两个监听器来捕捉success和error两种情形,而且需要调用open()和send()方法。
functionreqListener(){ vardata=JSON.parse(this.responseText); console.log(data); } functionreqError(err){ console.log('FetchError:-S',err); } varoReq=newXMLHttpRequest(); oReq.onload=reqListener; oReq.onerror=reqError; oReq.open('get','./api/some.json',true); oReq.send();
Fetch
我们的fetch请求的代码基本上是这样的:
fetch('./api/some.json') .then( function(response){ if(response.status!==200){ console.log('Looksliketherewasaproblem.StatusCode:'+ response.status); return; } //Examinethetextintheresponse response.json().then(function(data){ console.log(data); }); } ) .catch(function(err){ console.log('FetchError:-S',err); });
我们首先检查请求响应的状态是否是200,然后才按照JSON对象分析响应数据。
fetch()请求获取的内容是一个Stream对象。也就是说,当我们调用json()方法时,返回的仍是一个Promise对象,这是因为对stream的读取也是异步的。
返回数据对象的元数据(Metadata)
在上面的例子中,我看到了服务器响应对象Response的基本状态,以及如何转换成JSON。返回的相应对象Response里还有很多的元数据信息,下面是一些:
fetch('users.json').then(function(response){ console.log(response.headers.get('Content-Type')); console.log(response.headers.get('Date')); console.log(response.status); console.log(response.statusText); console.log(response.type); console.log(response.url); });
响应的对象Response类型
当我们执行一个fetch请求时,响应的数据的类型response.type可以是“basic”,“cors”或“opaque”。这些类型用来说明应该如何对待这些数据和数据的来源。
当请求发起自同一个域时,响应的类型将会是“basic”,这时,对响应内容的使用将没有任何限制。
如果请求来自另外某个域,而且响应的具有CORs头信息,那么,响应的类型将是“cors”。“cors”和“basic”类型的响应基本是一样的,区别在于,“cors”类型的响应限制你只能看到的头信息包括`Cache-Control`,`Content-Language`,`Content-Type`,`Expires`,`Last-Modified`,和`Pragma`。
“opaque”类型的响应说明请求来自另外一个域,并且不具有CORS头信息。一个opaque类型的响应将无法被读取,而且不能读取到请求的状态,无法看到请求的成功与否。当前的fetch()实现无法执行这样的请求。
你可以给fetch请求指定一个模式,要求它只执行规定模式的请求。这个模式可以分为:
“same-origin”只有来自同域的请求才能成功,其它的均将被拒绝。
“cors”允许不同域的请求,但要求有正确的CORs头信息。
“cors-with-forced-preflight”在执行真正的调用前先执行preflightcheck。
“no-cors”目前这种模式是无法执行的。
定义模式的方法是,使用一个参数对象当做fetch方法的第二个参数:
fetch('http://some-site.com/cors-enabled/some.json',{mode:'cors'}) .then(function(response){ returnresponse.text(); }) .then(function(text){ console.log('Requestsuccessful',text); }) .catch(function(error){ log('Requestfailed',error) });
串联Promises
Promises最大的一个特征是,你可以串联各种操作。对于fetch来说,我们可以在各个fetch操作里共享一些逻辑操作。
在使用JSONAPI时,我们需要检查每次请求响应的状态,然后解析成JSON对象。使用promise,我们可以简单的将分析状态和解析JSON的代码放到一个单独函数里,然后当做promise返回,这样就是代码更条理了。
functionstatus(response){ if(response.status>=200&&response.status<300){ returnPromise.resolve(response) }else{ returnPromise.reject(newError(response.statusText)) } } functionjson(response){ returnresponse.json() } fetch('users.json') .then(status) .then(json) .then(function(data){ console.log('RequestsucceededwithJSONresponse',data); }).catch(function(error){ console.log('Requestfailed',error); });
我们用status函数来检查response.status并返回Promise.resolve()或Promise.reject()的结果,这个结果也是一个Promise。我们的fetch()调用链条中,首先如果fetch()执行结果是resolve,那么,接着会调用json()方法,这个方法返回的也是一个Promise,这样我们就得到一个分析后的JSON对象。如果分析失败,将会执行reject函数和catch语句。
你会发现,在fetch请求中,我们可以共享一些业务逻辑,使得代码易于维护,可读性、可测试性更高。
用fetch执行表单数据提交
在WEB应用中,提交表单是非常常见的操作,用fetch来提交表单数据也是非常简洁。
fetch里提供了method和body参数选项。
fetch(url,{ method:'post', headers:{ "Content-type":"application/x-www-form-urlencoded;charset=UTF-8" }, body:'foo=bar&lorem=ipsum' }) .then(json) .then(function(data){ console.log('RequestsucceededwithJSONresponse',data); }) .catch(function(error){ console.log('Requestfailed',error); });
在Fetch请求里发送用户身份凭证信息
如果你想在fetch请求里附带cookies之类的凭证信息,可以将credentials参数设置成“include”值。
fetch(url,{ credentials:'include' })
显而易见,fetchAPI相比起传统的XMLHttpRequest(XHR)要简单的多,相比起jQuery里提供ajaxAPI也丝毫不逊色。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。