Fetch and its polyfill

Fetch API提供了一个获取资源的接口。

Basic Fetch

提到获取资源大家都会想到 XHR(XMLHttpRequest),以及通过这个接口实现的Ajax。这是传统的获取数据请求资源的方法。XMLHttpRequest并不是一个最完美的API,配置和调用显得有点混乱,加上是基于事件的异步模型,也没有现在的promise,async/await优雅。Fetch的出现就是为了解决这个问题,看一下使用传统XHR和Fetch分别请求数据的写法:

XHR:

var xmlhttp;
if (window.XMLHttpRequest) {
  xmlhttp = new XMLHttpRequest();
} /*else if (window.ActiveXObject) {
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); //IE5-IE6
*/}
xmlhttp.open('Get', url, true);
xmlhttp.responseType = 'json';

//进度xmlhttprequest level2
//xmlhttp.addEventListener("progress", updateProgress, false);

//完成
xmlhttp.addEventListener("load",handleComplete, false);

//失败
xmlhttp.addEventListener("error", handleFailed, false);

xmlhttp.send();

Fetch API:

fetch('/users.json') .then( function (response) { 
  return response.json();
}).then(function (json) {
  console.log('parsed json', json) ;
}).catch(function(ex) { 
  console.log('parsing failed', ex) 
});

Fetch API使用 Javascript Promises 来处理返回值或者是回调。如果你没用使用过promise,就去学咯,因为很快他就会随处可见了。

Fetch Usage

Fetch Header 允许通过执行new Header() 来灵活的设置一个请求头Header:

var head = new Headers();

//add new 
head.append('Content-Type', 'text/xml');
head.append('X-My-Custom-Header', 'CustomValue');

//has, get,set,delete,initial
head.get('Content-Type'); // text/xml
head.set('Content-Type', 'text/xml');
.....

你也可以在一个Request实例中使用Header:

var request = new Request(url, {
  headers: new Headers({
    'Content-Type': 'text/xml'
  })
});
fetch(request).then(function() {
  // handle response
});

Fetch Request可以通过Fetch Request来发送一个请求Request:

var request = new Request(url, {
  method: 'post',
  mode: 'cors',
  redirect: 'follow',
  headers: new Headers({
    'Content-Type': 'text-plain'
  })
});
fetch(request).then(function() {
  //handle response
})

Fetch Response Fetch 的 then 方法提供了一个 response实例,你可以手动创建一个Response,但是更多情况下是作为另一个API调用的返回结果。比如 Service Worker 的 Fetchevent.responseWith 或者是简单的Fetch API调用。 Response:

var response = new Response('....', {
  ok: false,
  status: 404,
  url: '/'
});

fetch('/')
  .then(funcyion(responseObject) {
    console.log('status: ', responseObject.status);
  }); 

fetch支持所有的 HTTP 方法,可以处理JSON,HTML,二进制返回值,比如:

处理JSON

fetch('/user.json')
  .then(function(response) {
    return response.json();
  }).then(function(json) {
    console.log('parsed json', json);
  }).catch(function(ex) {
    console.log('parsing failed', ex);
  });

发送表单

fetch('/submit-json', {
  method: 'post', 
  body: JSON.stringify({ 
    email: document.getElementById('email').value,
    answer: document.getElementById('answer').value
  })
});

注意
1.Fetch请求默认不带cookie,但是这可以通过 fetch(url, {credentials: 'same-origin'})设置同域,fetch(url, {credentials: 'include'})设置跨域。
2.服务器返回错误码的时候并不会reject,只有发生网络错误,或者是请求拦截的时候会reject。

fetch是一个优雅的资源获取方案。也是一个正在研究中的方案,目前的原生支持率并不高,使用起来很麻烦,幸运的是目前开源了许多的polyfill,引入之后IE9以上都可以完美支持。比如:github/fetch,除此之外还有 fetch-jsonp, fetch-ie8等polyfill,引入之后基本可以在IE8以上的生产环境使用。

扩展阅读

  1. MDN Fetch API
  2. github/fetch
  3. MDN es6-promise
  4. whatwg fetch
  5. deep fetch

你可能感兴趣的:(Fetch and its polyfill)