【译】Fetch API

fetch是一种使用 promise 为构建块的现代异步网络请求方法javascript

简介

1998年发布的IE5,让咱们可以使用 XMLHttpRequest (XHR) 对象在浏览器中进行异步网络请求。 在此后的几年,GMail 和其余丰富的应用程序大量使用它,并使该方法如此受迎,以致于它必须有一个名称:AJAX。 直接使用 XMLHttpRequest 一直很痛苦,因此它常常被一些库抽象集成,比较有表明性的好比说 jQuery 使用 XHR 封装了本身的辅助函数,好比:html

  • jQuery.ajax()
  • jQuery.get()
  • jQuery.post()
  • ...

这些方法对更方便的使用 XHR 发送异步请求有很大的影响,特别是它们也确保了在旧浏览器上也可以正常工做。Fetch,是当今进行异步网络请求的新标准,而且使用了 Promise 做为构建块,除了 IE 以外,Fetch 在各主要浏览器中都可以获得很好的支持。 java

browser-support
另外 Github 提供了fetch方法的 Polyfill,让咱们能够在任何浏览器里面使用 fetch。

使用Fetch

使用 Fetch 方法发起 GET 请求是很是简单的:ios

fetch('/file.json')
复制代码

当你已经开始使用它:fetch 将会向相同的域名发起一个 HTTP 请求以得到域名下 file.json 资源。 如您看见的那样,fetch 方法可在全局 window 做用域下得到,如今咱们让它变得更有意义,它在实际状况下的使用下多是这样的:git

fetch('./file.json')
  .then(response => response.json())
  .then(data => console.log(data))
复制代码

调用 fetch() 会返回一个 promise 对象,咱们能够等待这个 promise 对象 resolve 以后将返回的结果传递给 promise 对象的 then 方法。then 里面的回调函数接收到的 fetch Promise 返回的对象,即 Response 对象。在下面会详细介绍这个 Response 对象。github

捕获错误

由于 fetch() 方法会返回一个 Promise 对象,咱们可使用 promise 对象的 catch 方法拦截在请求执行过程当中发生的任何错误,以及在 then 的回调函数中的处理结果:ajax

fetch('./file.json')
.then(response => {
  //...
})
.catch(err => console.error(err))
复制代码

另外一个捕获请求发生错误的方法是在第一个 then 里面对它进行处理json

fetch('./file.json')
.then(response => {
  if (!response.ok) { throw Error(response.statusText) }
  return response
})
.then(response => {
  //...
})
复制代码

响应对象

调用 fetch() 返回的响应对象包含有关网络请求和响应的全部信息。axios

元数据

headers

经过访问响应对象上的 headers 属性使您可以查看请求返回的 HTTP 头:api

fetch('./file.json').then(response => {
  console.log(response.headers.get('Content-Type'))
  console.log(response.headers.get('Date'))
})
复制代码

HTTP Headers


status

此属性是表示 HTTP 响应状态的整数 ( 响应头部的状态码 )。

  • 101,204,205 或 304 是响应体没有数据的状态
  • 200 到299,包括两边的值,是一个OK状态(成功)
  • 301,302,303,307 或 308 是重定向
fetch('./file.json').then(response => console.log(response.status))
复制代码
statusText

statusText 是表示响应状态消息的属性。若是请求成功,则状态为OK。

fetch('./file.json').then(response => console.log(response.statusText))
复制代码
url

url 是表示咱们请求资源的完整 URL 的属性

fetch('./file.json').then(response => console.log(response.url))
复制代码

响应主体内容

能够经过下面这些方法获得响应主体的内容:

  • text()将主体内容做为字符串返回
  • json()将主体内容通过 JSON.parse 转换后返回
  • blob()将主体内容做为 Blob 对象返回
  • formData()将主体内容做为 FormData 对象返回
  • arrayBuffer()将主体内容做为 arrayBuffer 对象返回

全部这些方法都会返回一个 Promise,好比说:

fetch('./file.json')
  .then(response => response.text())
  .then(body => console.log(body))
复制代码
fetch('./file.json')
  .then(response => response.json().catch(()=>({})))//响应状态码为 200 但没有响应主题内容的时候,使用json()方法会报错,所以须要catch到这个错误
  .then(body => console.log(body))
复制代码

text json


可使用 ES2017 的 async 方法对上面的方法进行改写:

;(async () => {
  const response = await fetch('./file.json')
  const data = await response.json()
  console.log(data)
})()
复制代码

请求对象

请求对象表示对资源的请求,一般能够由 new Request() 方法生成。 好比说:

const req = new Request('/api/todos')
复制代码

请求对象提供了一些只读属性来检查请求的详细信息,包括:

  • method:请求的方法,包括:GET、POST、PUT、HEAD、DELETE 等等
  • url:请求的 URL
  • headers:请求的关联请求头的对象
  • referrer:请求的引用者
  • cache:请求的缓存模式(好比说:default、reload、no-cache) 还公开了一些处理请求主体的方法:json()text()formData() 完整的 API 能够在 Request 中找到。

请求头部

咱们常常须要可以设置 HTTP 请求头部,fetch 使咱们可以用 Headers 对象执行此操做:

const headers = new Headers()
headers.append('Content-Type', 'application/json')
复制代码

或者写成👇这样:

const headers = new Headers({
  'Content-Type': 'application/json'
})
复制代码

要使请求带上请求头,咱们将 Request 对象传给 fetch() 而不是只传 URL。 相比于:

fetch('./file.json')
复制代码

咱们这样作:

const request = new Request('./file.json', {
  headers: new Headers({
    'Content-Type': 'application/json'
  })
})
fetch(request)
复制代码

Header 对象不只能够设置键值对,咱们也能够查询其中的值:

headers.has('Content-Type')
headers.get('Content-Type')
复制代码

而且,咱们也能够删除以前设置的请求头:

headers.delete('X-My-Custom-Header')
复制代码

POST 请求

Fetch 也容许在咱们的请求中使用其余的 HTTP 请求方法,好比说:POST, PUT, DELETE 或者 OPTIONS。 在请求对象的 method 属性中指定方法,并在请求头和请求体中传递其他参数: POST 请求的例子:

const options = {
  method: 'post',
  headers: {
    'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
  },
  body: 'name=Flavio&test=1'
}

fetch(url, options).catch(err => {
  console.error('Request failed', err)
})
复制代码

怎么取消 fetch 请求

fetch 被推出的这几年,一旦使用 fetch 发起一个请求就没有办法终止这个请求,如今,咱们能够经过引入通用 API: AbortController 和 AbortSignal 来通知停止事件。 您能够将 signal 做为 fetch 的参数传递给 fetch

const controller = new AbortController()
const signal = controller.signal

fetch('./file.json', { signal })
复制代码

好比,您能够设置一个定时器当 fetch 请求执行 5s 以后终止请求:

setTimeout(() => controller.abort(), 5 * 1000)
复制代码

即便这个请求已经返回了,调用 abort() 也不会致使任何错误, 当停止信号发出后,fetch 将会由被叫作 AbortErrorDOMException对象(DOMException是W3C DOM核心对象。DOMException接口表示一个处理的错误,当一个操做不可能执行的时候,会抛出一个异常。例如试图建立一个无效的DOM, 或经过一个不存在的节点做为参数节点操做方法)reject 返回的 promise:

fetch('./file.json', { signal })
  .then(response => response.text())
  .then(text => console.log(text))
  .catch(err => {
    if (err.name === 'AbortError') {
      console.error('Fetch aborted')
    } else {
      console.error('Another error', err)
    }
  })
复制代码

阅读更多

网络请求很是难,对吗?您可能发现了当您须要一些基于 Fetch 构建的附加功能时, Axios 这个 JavaScript 库更加符合您的需求,那如今就去学习吧!

原文地址
扩展阅读:XMLHttpRequest对象

相关文章
相关标签/搜索