Fetch 参考: https://developers.google.com...
如今可能还有一些很旧的程序还在使用XHR,相似下面的写法:php
const request = new XMLHttpRequest() request.responseType = 'json' request.open('GET', '/url', true) request.onload = () => { console.log(request.response) } request.onerror = () => { console.log('shits happen!') } request.send(null)
这样子使用XHR进行异步访问、读取资源显得很繁琐,相对比Fetch()容许你建立相似XHR的network访问,可是使用更简单并且干净的API,不须要屡次回调而且记住XHR复杂的API。Fetch API底层是经过Promises实现。
XMLHttpRequest 一个相对完整的XMLHttpRequest至少须要监听两个事件(onload、onerror)来实现成功和失败的回调,以及调用open()和send()web
function reqListener() { var data = JSON.parse(this.responseText); console.log(data); } function reqError(err) { console.log('Fetch Error :-S', err); } var oReq = new XMLHttpRequest(); oReq.onload = reqListener; oReq.onerror = reqError; oReq.open('get', './api/some.json', true); oReq.send();
Fetch 一个简单的Fetch例子以下:json
fetch('./api/some.json') .then( function(response) { if (response.status !== 200) { console.log('Looks like there was a problem. Status Code: ' + response.status); return; } // Examine the text in the response response.json().then(function(data) { console.log(data); }); } ) .catch(function(err) { console.log('Fetch Error :-S', err); });
Fetch的语法更加语义化、比较好理解。在上面的例子里咱们先判断response的status码,若是是200咱们才将response解析为JSON
fetch()请求返回的response是Stream对象,所以咱们调用response.json时因为异步读取流对象因此返回的是一个Promise对象。
Fetch用async优化代码 因为Fetch底层是用Promise实现,咱们能够直接用async来优化上面的代码,减小回调,使其更加语义化、容易理解api
async function geturl(){ try{ let res = await fetch('./api/some.json') if(res.status == 200){ console.log(await res.text()) } } catch(err){ console.log(err) } }
Response元数据 在上面的例子里,咱们了解了Response对象的status状态以及怎么把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响应会自带一个response.type属性(basic、cors、opaque)。response.type属性说明了异步资源的来源,同时还有相应的处理方式。
当咱们发起一个同源请求时,response.type为basic,并且你能够从response读取所有信息。
若是咱们访问一个非同源域名,而且有返回相应的CORs响应头时,那么该请求类型是cors。cors和basic很类似,就除了cors响应里你没法访问cookie
Cache-Control
,app
Content-Language
,cors
Content-Type
,异步
Expires
,async
Last-Modified
和
Pragma
当咱们对一个不一样源的域名发起请求时,若是返回的响应头部没有CORS信息,那么这个response对应的类型就是opaque类型。一个opaque响应是没法读取返回的数据、状态,甚至没法肯定这个请求是否成功。
咱们能够自定义Fetch请求的模式,要求返回对应类型的响应,有如下几种响应:
same-origin 只返回同源请求,其余类型会被reject
cors 接收同源、非同源请求,返回有CORs头部的响应
cors-with-forced-preflight 在发出请求前会先作一次安全性检查
no-cors 用来发起没有CORS头部而且非同源请求,而且会返回opaque响应。可是目前这种类型只能在Service Worker里使用,在window.fetch里不能用
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'}) .then(function(response) { return response.text(); }) .then(function(text) { console.log('Request successful', text); }) .catch(function(error) { log('Request failed', error) });
承诺链 由于Fetch返回的response是基于Promise实现,因此咱们能够像链条同样把几个Promise串接起来,以下所示:
function status(response) { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response) } else { return Promise.reject(new Error(response.statusText)) } } function json(response) { return response.json() } fetch('users.json') .then(status) .then(json) .then(function(data) { console.log('Request succeeded with JSON response', data); }).catch(function(error) { console.log('Request failed', error); });
固然了,咱们也能够用async进行代码优化
async function geturl(url){ try { let res = await fetch(url) if(res.status >= 200 && res.status < 300){ console.log('Request succeeded with JSON response', await res.json()) } }catch (err){ console.log(err) } } geturl('users.json')
Post请求 当咱们使用Fetch发起Post请求时,须要手动设置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('Request succeeded with JSON response', data); }) .catch(function (error) { console.log('Request failed', error); });
若是没有显式指定method参数,那么默认Get请求
带Cookie发送请求 若是咱们想要在异步请求中带上cookie参数,那么须要显式指定credentials参数:
fetch(url, { credentials: 'include' })
转载于猿2048:→《浅谈 Fetch》