Fetch 使用教程

window 自带了 window.fetch 方法, 在最新版的 Firefox 和 Chrome 中已经提供支持,其他浏览器还有兼容性问题,要做兼容性处理。

一、fetch 安装

为了解决 fetch 的兼容性,我们使用 Fetch Polyfill 的版本  whatwg-fetch。

npm install --save whatwg-fetch
import 'whatwg-fetch'

也可以用另一个 fetch 版本 isomorphic-fetch

npm install --save isomorphic-fetch
import fetch from "isomorphic-fetch";

二、fetch 的基本使用

// url (必须), init对象 (可选)
fetch(url, init).then(function(res) {
    // fetch第一次拿到的是整个Response对象,要调用json()方法转成含有json数据的Promise
    return res.json();
}).catch(function(err) {
    // 中途任何地方出错...在此处理
});

GET 请求

fetch('http://localhost:8082/data/users.json?id=99')
  .then(function(res) {
    return res.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

POST请求

请求参数以json形式传给后端

fetch('/api/getItems', {
    body: JSON.stringify(params), //json字符串和对象都可以,推荐使用json字符串,这样可以在控制台network里看到请求参数
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'include', // include, same-origin, *omit
    headers: {
      'Content-Type': 'application/json'
    },
    method: 'POST'
  }).then(response => response.json()).then(res => {
      console.log(res)
  })

请求参数以formData形式传给后端

import qs from 'query-string';

fetch('/api/getItems', {
    body: qs.stringify(params), //使用query-string把参数转换成'name=jim&age=22'形式,也可以直接用formData格式作为参数
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'include', // include, same-origin, *omit
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    method: 'POST'
  }).then(response => response.json()).then(res => {
      console.log(res)
  })

上传文件

可以通过HTML元素,FormData() 和fetch()上传文件。

var formData = new FormData();
var fileField = document.querySelector("input[type='file']");

formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);

fetch("/api/uploadFile", {
  method: "PUT",
  body: formData
})
  .then(response => response.json())
  .catch(error => console.error("Error:", error))
  .then(response => console.log("Success:", response));

new FormData() 可以直接传一个 form 元素作为参数。

{
    body: new FormData(document.getElementById('myForm'))
}

上传多个文件

var formData = new FormData();
var photos = document.querySelector("input[type='file'][multiple]");

formData.append('title', 'My Vegas Vacation');
formData.append('photos', photos.files);

fetch('https://example.com/posts', {
  method: 'POST',
  body: formData
})
.then(response => response.json())
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));

三、自定义请求对象

除了传给 fetch() 一个url,你还可以通过使用 Request() 构造函数来创建一个 request 对象,然后再作为参数传给 fetch()

var myHeaders = new Headers();

var myInit = { 
    method: 'GET',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' 
};

var myRequest = new Request('/api/getItems', myInit);

fetch(myRequest).then(function(response) {
  return response.json();
}).then(function(res) {
    console.log(res)
});

Request() 和 fetch() 接受同样的参数。你甚至可以传入一个已存在的 request 对象来创造一个拷贝:

var anotherRequest = new Request(myRequest,myInit);

这个很有用,因为 request 和 response bodies 只能被使用一次(译者注:这里的意思是因为设计成了 stream 的方式,所以它们只能被读取一次)。创建一个拷贝就可以再次使用 request/response 了,当然也可以使用不同的 init 参数。

注意clone() 方法也可以用于创建一个拷贝。它在语义上有一点不同于其他拷贝的方法。其他方法(比如拷贝一个 response)中,如果 request 的 body 已经被读取过,那么将执行失败,然而 clone() 则不会失败。

四、其他

        当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。当状态码在200-299之间时,ok 属性才会返回 true。

        默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项为 include)。自从2017年8月25日后,默认的credentials政策变更为same-originFirefox也在61.0b13中改变默认值

五、Init 对象

一个配置项对象,包括所有对请求的设置。可选的参数有:

1. method - 支持 GETPOSTPUTDELETEHEAD

2. headers - 对应的 Headers 对象

3. body - 请求参数

4. credentials - 设置 cookies 是否随请求一起发送。

   可选值: omit: (默认, 不发送 Cookie)

       same-origin:同域下自动发送 Cookie

       include:始终发送 Cookie,即使是跨域。

5. mode - 是否允许跨域请求,以及哪些响应的属性是可读的。

    可选值:cors(默认, 允许跨域请求,将遵守 CORS 协议

        no-cors该模式允许来自 CDN 的脚本、其他域的图片和其他一些跨域资源。前提条件是请求的 method 只能是 HEAD、GET 或 POST。而且 js 不能访问 Response 对象中的任何属性

                 same-origin:要同源,不允许跨域

        navigate:支持导航的模式,仅用于 HTML 导航。

6. cache - 设置缓存模式。

    可选值: default:浏览器在其 HTTP 缓存中查找匹配的请求。

             a. 如果匹配并且是新鲜的,它将从缓存中返回。

             b. 如果存在匹配但已失效,则浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新。

             c. 如果没有匹配,浏览器将发出正常的请求,并且下载的资源更新缓存。

         no-store:浏览器从远程服务器获取资源,而不先查看缓存,并且不会使用下载的资源更新缓存。

         reload:浏览器从远程服务器获取资源,而不先查看缓存,但随后将使用下载的资源更新缓存。

         no-cache:浏览器在其 HTTP 缓存中查找匹配的请求。

             a. 如果匹配,新鲜或陈旧,浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新。

             b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。

         force-cache:浏览器在其 HTTP 缓存中查找匹配的请求。

             a. 如果有匹配,新鲜或陈旧,它将从缓存中返回。

             b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。

         only-if-cached:浏览器在其 HTTP 缓存中查找匹配的请求。只能用在 mode 为 same-origin 的情况下

             a. 如果匹配,新鲜或陈旧,将从缓存中返回。

             b. 如果没有匹配,浏览器将返回一个错误。

7. referrer - 请求的引用者(例如:client)

8. redirect - 定义重定向处理方式。

      可选值:follow(默认), error, manual。

9. integrity - 子资源完整性值。

 

六、Body

不管是请求还是响应都能够包含body对象. body也可以是以下任意类型的实例

  • ArrayBuffer
  • ArrayBufferView (Uint8Array等)
  • Blob/File
  • string
  • URLSearchParams
  • FormData

Body 类定义了以下方法 (这些方法都被 Request 和Response所实现)以获取body内容. 这些方法都会返回一个被解析后的Promise对象和数据.

  • arrayBuffer()
  • blob()
  • json()
  • text()
  • formData()
fetch("/api/getItems").then(res => {
  return res.json();
});

 

 

参考文献:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

 

 

 

你可能感兴趣的:(AJAX)