Fetch的基本用法

3,609 阅读4分钟

由于 FetchAPI 是基于 Promise 设计,有必要先学习一下 Promise,推荐阅读 MDN Promise 教程
本文章内容推荐阅读 MDN Fetch 教程

语法说明

fetch(url, options).then(function(response) {
  // handle HTTP response
}, function(error) {
  // handle network error
})
<script>
        fetch('http://localhost:3000/data').then((data) => {
              /*   text()方法属于fetchApi的一部分,它返回一个Promise实例对象 ,用于获取后台数据 -   
                   再用`.then()`才可以获取数据 */
            return data.text()

        }).then(function (data) {
            // 注意这里data得到的才是最终数据
            console.log(data)
        })
    </script>

具体参数案例:

//兼容包
require('babel-polyfill')
require('es6-promise').polyfill()

import 'whatwg-fetch'

fetch(url, {
  method: "POST",
  body: JSON.stringify(data),  // data can be `string` or {object}!
  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

  response.text().then(function(responseText) { ... })
}, function(error) {
  error.message //=> String
})

url

定义要获取的资源。这可能是:

  • 一个 USVString 字符串,包含要获取资源的 URL
  • 一个 Request 对象。

options(可选)

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

  • method: 请求使用的方法,如 GETPOSTDELETEPUT

  • headers: 请求的头信息,形式为 Headers 对象或 ByteString

  • body: HTTP的请求参数,请求的 body 信息:可能是一个 BlobBufferSourceFormDataURLSearchParams 或者 USVString 对象。注意 GET 或 DELETE 方法的请求不能包含 body 信息。

  • mode: 请求的模式,如 cors、 no-cors 或者 same-origin

  • credentials: 请求的 credentials,如 omitsame-origin 或者 include

  • cache: 请求的 cache 模式: defaultno-storereloadno-cacheforce-cache, 或者 only-if-cached。 options 是一个对象,可设置以下字段:

  • method:请求方法,默认GET;

  • headers:请头信息,可以是简单的对象,也可以是 Headers 的实例;

  • body:发送数据。BlodbufferSourceFormDataURLSearchParamsUSVstring,GET、HEAD 没有body;

  • mode:请求模式。

    • cors:跨域请求;
    • no-cors:只允许使用GETHEADPOST;
    • same-origin:同源请求;
    • navigate:支持页面导航(不太明白)。
  • credentials:是否发送 cookies

    • omit:不发送,默认;
    • same-origin:同源发送;
    • include:发送。
  • cache:缓存策略:

    • default:请求之前检查缓存;
    • no-cache:有缓存,发送一个查询请求,缓存失效,再发送正常请求;
    • no-store:不检查缓存,直接请求;
    • reload:忽略缓存,拿到响应后,更新缓存;
    • force-cache:强制读取缓存,缓存过期,再发送正常请求;
    • only-if-cached:读取缓存,过期就报网络错误。 mode 设置为 same-origin 时有效。
  • redirect:重定向时的处理方法:

    • follow:跟随;
    • error:报错;
    • manual:用户手动跟随。
  • integrity:包含一个验证资源完整性的字符串。

response

一个 Promiseresolve 时回传 Response 对象:

  • 属性:

    • status (number) - HTTP请求结果参数,在100–599 范围
    • statusText (String) - 服务器返回的状态报告
    • ok (boolean) - 如果返回200表示请求成功则为true
    • headers (Headers) - 返回头部信息,下面详细介绍
    • url (String) - 请求的地址
  • 方法:

    • text() - 以string的形式生成请求text
    • json() - 生成JSON.parse(responseText)的结果
    • blob() - 生成一个Blob
    • arrayBuffer() - 生成一个ArrayBuffer
    • formData() - 生成格式化的数据,可用于其他的请求
  • 其他方法:

    • clone()
    • Response.error()
    • Response.redirect()

response.headers

  • has(name) (boolean) - 判断是否存在该信息头
  • get(name) (String) - 获取信息头的数据
  • getAll(name) (Array) - 获取所有头部数据
  • set(name, value) - 设置信息头的参数
  • append(name, value) - 添加header的内容
  • delete(name) - 删除header的信息
  • forEach(function(value, name){ ... }, [thisContext]) - 循环读取header的信息

实例

get请求方式的参数传递 两种传参的方式:

?id=123 与 /123 等价

image.png

DELETE请求方式的参数传递:

image.png

POST两种请求方式的参数传递

image.png

image.png

PUT请求方式的参数传递

image.png

fetch响应结果

<script>
        fetch('http://localhost:3000/data').then((data) => {
            //return data.text()
            
            return data.json()
        }).then(function (data) {
                //data.json()得到的是json对象,可以用data.name直接调用单个属性

               //data.text()得到的是字符串,不能直接调用

            //console.log(data)
            console.log(data.name)
        })
    </script>

支持状况及解决方案

原生支持率并不高,幸运的是,引入下面这些 polyfill 后可以完美支持 IE8+ :

  • 由于 IE8 是 ES3,需要引入 ES5 的 polyfilles5-shimes5-sham
  • 引入 Promise 的 polyfilles6-promise
  • 引入 fetch 探测库:fetch-detector
  • 引入 fetch 的 polyfillfetch-ie8
  • 可选:如果你还使用了 jsonp,引入 fetch-jsonp
  • 可选:开启 Babel 的 runtime 模式,现在就使用 async/await

Fetch Vs AJAX

  • 响应状态为404或5xx,都resolve,但是 ok 为false。只有当网络故障或者请求被阻止了,才会 reject
  • 默认情况不发送不接收cookies,需要设置;
  • POST 的数据需要转为JSON;
  • 不能设置超时和取消请求,可以通过Promise.race,了模拟两者;
  • 文件上传和下载获取不到进度,可使用 response.body 是可读流,具有getReader,可根据这个来获取下载进度。;
  • 不能直接获取到响应数据,需要调用响应方法,resolve 一下;

总结

  • Fetch API 很底层,使用起来并不丝滑;
  • Fetch 错误处理有点复杂;
  • Fetch 不支持取消和超时设置;
  • 上传和下载进度没有,使用可读流来获取,复杂性突然升高了。

还是使用原生的 xhr 和 axios 库来的爽快。