你不须要jQuery(三):新AJAX方法fetch()

XMLHttpRequest来完成ajax有些老而过期了。javascript

fetch()能让咱们完成相似 XMLHttpRequest (XHR) 提供的ajax功能。它们之间的主要区别是,Fetch API 使用了 Promises,它让接口更简单、简洁,避免了回调的复杂性,省去了使用复杂的 XMLHttpRequest API。java

若是你以前未使用过 Promises,你应该先看看《JavaScript Promises 用法》这篇文章。web

基本Fetch用法

让咱们先用一个例子来比较一下使用 XMLHttpRequest 和使用 fetch 之间的不一样。咱们要请求一个URL,获取JSON格式的返回结果。ajax

XMLHttpRequest

一个 XMLHttpRequest 请求须要两个监听器来捕捉 success 和 error 两种情形,并且须要调用 open() 和 send() 方法。json

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 请求的代码基本上是这样的:api

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);  
  });

  

咱们首先检查请求响应的状态是不是 200,而后才按照 JSON 对象分析响应数据。promise

fetch()请求获取的内容是一个 Stream 对象。也就是说,当咱们调用 json() 方法时,返回的还是一个 Promise 对象,这是由于对 stream 的读取也是异步的。服务器

返回数据对象的元数据(Metadata)

在上面的例子中,我看到了服务器响应对象Response的基本状态,以及如何转换成JSON。返回的相应对象Response里还有不少的元数据信息,下面是一些:cookie

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”。这些类型用来讲明应该如何对待这些数据和数据的来源。app

当请求发起自同一个域时,响应的类型将会是“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” 在执行真正的调用前先执行preflight check
  • “no-cors” 目前这种模式是没法执行的。

定义模式的方法是,使用一个参数对象当作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)  
  });

  

串联 Promises

Promises最大的一个特征是,你能够串联各类操做。对于fetch来讲,咱们能够在各个fetch操做里共享一些逻辑操做。

在使用JSON API时,咱们须要检查每次请求响应的状态,而后解析成JSON对象。使用promise,咱们能够简单的将分析状态和解析JSON的代码放到一个单独函数里,而后当作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);  
  });

  

咱们用 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('Request succeeded with JSON response', data);  
  })  
  .catch(function (error) {  
    console.log('Request failed', error);  
  });

  

在Fetch请求里发送用户身份凭证信息

若是你想在fetch请求里附带cookies之类的凭证信息,能够将 credentials参数设置成 “include” 值。

fetch(url, {  
  credentials: 'include'  
})

  显而易见,fetch API相比起传统的 XMLHttpRequest (XHR) 要简单的多,相比起jQuery里提供ajax API也丝绝不逊色。

相关文章
相关标签/搜索