网络请求系列(一)——Fetch

什么是Fetch

Fetch是全局对象window的一个方发,是XMLHttpRequest一个更现代化的替代方案。
Fetch暂时不支持abort request。
Fetch是基于promise的。
javascript

使用方法

Fetch返回一个promise,能够使用then来处理结果,或者搭配async/await使用。
let promise = fetch(url, [options])java

先看一个最简单的get用法示例:git

// url (required), options (optional)
fetch('https://davidwalsh.name/some/url', {
  method: 'get'
}).then(function(response) {
  // response....
}).catch(function(err) {
  // Error...
});
复制代码

下面是一个稍微复杂的post用法示例:github

fetch(url, {
  method: 'POST',
  body: JSON.stringify(data),
  headers: {
    "Content-Type": "application/json"
  },
  credentials: "same-origin"
}).then(function(response) {
  response.status     //=> number 100-599
  response.statusText //=> String
  response.headers    //=> Headers
  response.url        //=> String

  return response.text()
}, function(error) {
  error.message //=> String
})
复制代码

Fetch使用Promises来处理response。Fetch接收两个参数:json

  • url:string类型,必选,发起请求的地址
  • options:object类型,可选,请求的配置参数

还能够使用Request对象实例做为参数的方式发起fetch请求:跨域

var request = new Request(url, options);
fetch(request).then(function(response) {
  // handle with response...
}).catch(function(err) {
  // Error...
});
复制代码

Options配置项

options能够配置如下参数:promise

  1. method (String) - HTTP 请求方法,默认:"GET"
  2. body (String, body types) - HTTP 请求主体,示例:
{
  body: new URLSearchParams([['foo', 1], ['bar', 2]]).toString()
}
复制代码

body的类型包括:浏览器

Class Default Content-Type
String text/plain;charset=UTF-8
URLSearchParams application/x-www-form-urlencoded;charset=UTF-8
FormData multipart/form-data
Blob inherited from the blob.type property
ArrayBuffer
TypedArray
DataView

其余数据结构须要预先编码为上述类型之一。例如,JSON.stringify(data)可用于将数据结构序列化为JSON字符串。bash

  1. headers (Object, Headers) - 请求头,默认:{},示例:
{
  headers: new Headers({
    'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
  }) 
}
复制代码

headers提供如下方法增删改查头部信息:服务器

  • has(name) (boolean)
  • get(name) (String)
  • set(name, value)
  • append(name, value)
  • delete(name)
  • forEach(function(value, name){ ... }, [thisContext])
  1. credentials (String) - 跨域请求时方身份验证凭证模式,默认:"omit" "omit" - 请求中不携带身份验证凭证(例如cookies)
    "same-origin" - 在对同一站点的请求中包含身份验证凭证
    "include" - 在全部站点的请求中包含身份验证凭证

响应结果Response

Response表示来自服务器的HTTP响应。Response会做为promise回调函数的参数。 包含如下属性:

  • status (number) - HTTP状态码,范围在100–599以内
  • statusText (String) - 响应文本,如:"Unauthorized"
  • ok (boolean) - status为2xx时表示响应成功,值为true
  • headers (Headers)
  • url (String)

此外,response还提供了一些方法处理成特定的数据格式并返回一个Promise:

  • text() - 以字符串形式生成响应文本
  • json() - 生成JSON.parse(responseText)的结果
  • blob() - 生成一个Blob
  • arrayBuffer() - 生成一个ArrayBuffer
  • formData() - 生成可转发到另外一个请求的表单数据

获取响应一般须要通过两个阶段:

  1. 第一阶段,当服务器发送了响应头,promise 就使用其内建的 Response 类来解析该对象,经过检测HTTP状态来肯定请求是否成功,或者当响应体尚未返回时,经过检查响应头来肯定状态。
  2. 第二阶段,为了获取响应体,须要调用上述text()等方法来获取不一样格式的响应正文。可是要注意只能选择其中一种解析响应体的方式,例如若是调用response.text() 方法来获取 response,而后再用 response.json() 方法是不会生效的,由于正文内容已经被处理过了。 例如获取一个图片文件:
let response = await fetch('/article/fetch/logo-fetch.svg');
let blob = await response.blob(); // 以 Blob 对象下载
img.src = URL.createObjectURL(blob);
复制代码

错误处理

若是出现网络错误或其余缘由致使HTTP请求没法完成,fetch()的promise 将会reject该error。 注意,在HTTP 4xx或5xx服务器响应的状况下,promise不会reject。这个promise将像HTTP 2xx同样正常resolve。能够经过检查response.status的状态码来决定如何处理错误:

fetch(...).then(function(response) {
  if (response.ok) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
})
复制代码

兼容状况

截至目前,fetch的浏览器兼容状况以下图所示: (能够在can I use这个网站查询浏览器兼容性)

若是想要兼容IE及老版本浏览器,能够使用polyfill:whatwg-fetch

Renerence

1.github.github.io/fetch/

2.louiszhai.github.io/2016/11/02/…

3.juejin.cn/post/684490…

4.davidwalsh.name/fetch

相关文章
相关标签/搜索