0
点赞
收藏
分享

微信扫一扫

Fetch&Fetch的二次封装

黎轩的闲暇时光 2022-01-23 阅读 66

前言

客户端服务器端通信方式ajax (ajax JQ的类库 /axios类库)  /jsonp  / fetch

fetch是Es6新提供的API:基于不同于​XMLHttpRequest的方式,基于客户端和服务器端的数据通信,而且本身是基于promise管理请求结果的(发送请求返回promi实例)

fetch的基础知识和管理

语法:

Promise<Response> fetch(input[, init]); :返回promise实例 input:URL地址 init:配置项

  • 基于fetch发送请求,只要服务器有响应结果,fetch都认为是成功的<promise的状态是fulfilled>
  • 默认情况下只有 断网 ,请求中断,请求超时等请况下,服务器不会有任何响应,fetch才会认为当前请求是失败的!!
  • 在成功的THEN方法中,我们需要根据HTTP状态码,手动校验成功还是失败!
  • 还需要把响应主体body中存储的数据变为想要的,一般都要json格式,并且监听是否转换成功

fetch目前不如XMLHttpRequest的机制完善(例如fetch中没有设置请求超时和请求中断的方法)

  • fetch请求超时如何处理:自己在发送请求后,设置定时器监听,如果请求先到则删掉定时器,如果定时器先到,则直接走catch失败情况
  • 对于中断请求目前有一个草案阶段的API可以实现AbortController

Response内置类

  • 返回的response对象是Response类的实例
  • status/statusText:http状态码及其描述
  • ok:状态码是200时为true
  • Response.headers 包含此 Response 所关联的 Headers 对象。
  • Response.redirected  表示该 Response 是否来自一个重定向,如果是的话,它的 URL 列表将会有多个条目。
  • Response.type  包含 Response 的类型(例如,basic、cors)是否跨域
  • Response.url  包含 Response 的URL。
  • Response.useFinalURL 包含了一个布尔值,来标示这是否是该 Response 的最终 URL Response 实现了 Body 接口,所以以下属性亦可用:
  • Body.body 一个简单的 getter,用于暴露一个 ReadableStream 类型的 body 内容。
  • Body.bodyUsed  包含了一个布尔值来标示该 Response 是否读取过 Body。

Response.prototype

这些方法的目的是:把body可读流对象解析出指定格式的数据 例如调用Response.json()会返回一个json格式对象的数据

执行方法会返回一个全新的promise,实例存储的值是想要的数据:服务器返回的响应主体内容有很多,当我们想执行某个方法转换为想要格式的时候,可能会成功,也可能会失败,所以在次基于promise管理

  • arrayBuffer() Buffer格式
  • blob()  二进制格式
  • neienformData()  文件上传 表单上传
  • json() json格式字符串
  • text()  纯字符串格式
  • Response.clone() 创建一个 Response 对象的克隆。
  • Response.error()返回一个绑定了网络错误的新的 Response 对象。
  • Response.redirect()  用另一个 URL 创建一个新的 Response。 Response 实现了 Body 接口,所以以下方法同样可用:

Headers内置类

headers:Headers内置类的实例对象(可以对请求头响应头信息做管理)

  • append /delete/ set:设置请求头/响应头
  • forEach/get/has/获取请求头/响应头
  • keys/entries/values迭代器信息

ReadableStream内置类

body:ReadableStream内置类的实例对象(可读流 存储服务器返回的响应主体信息)

init 配置项

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

  • method: 请求方式:GET*/POST/DELETE/HEAD/PUT...
  • headers设置请求头信息 自定义请求头信息{Headers对象 & 普通对象}
  • body: 设置请求主体信息(只有post系列请求才可以设置,get系列请求会报错,格式有要求:json字符串,URLENCODED格式字符串,普通字符串,FormData格式对象,Buffer/bolb格式...不能是普通对象,并且要根据请求主体的数据格式,配置相关的请求头(Content-Type)
  • mode: 请求的模式,如 cors、 no-cors 或者 same-origin。
  • credentials: 是否允许携带资源凭证 include(同源跨域都允许)same-origin(同源才允许)omit都不允许
  • cache:  请求的 cache 模式: default、 no-store、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
  • redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中默认使用follow(Chrome 47之前的默认值是manual)。
  • referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。
  • referrerPolicy: 指定了HTTP头部referer字段的值。可能为以下值之一: no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。
  • integrity: 包括请求的  subresource integrity 值 

[扫盲] 客户端基于请求主体传递给服务器的格式

  • json字符串
  • urlenccoded格式字符串
  • formData格式对象

代码

import { Message } from 'element-ui';
//创造一个中断控制器
let controller = new AbortController();
//自定义请求头信息{Headers对象 & 普通对象}
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded')
headers.append('name', 'lisa')
fetch('/api/getTaskList', {
    method: 'GET',//请求方式:GET*/POST/DELETE/HEAD/PUT...
    headers,//设置请求头信息
    body: '',//设置请求主体信息(只有post系列请求才可以设置,get系列请求会报错,格式有要求:json字符串,URLENCODED格式字符串,普通字符串,FormData格式对象,Buffer/bolb格式...不能是普通对象,并且要根据请求主体的数据格式,配置相关的请求头(Content-Type)
    credentials: 'include',//是否允许携带资源凭证 include(同源跨域都允许)same-origin(同源才允许)omit都不允许
    //给fetch请求设置信号器
    signal: controller.signal
})
    .then(response => {
        let { status, statusText } = response;
        if (!/^2\d{2}$/.test(status)) {
            //失败:状态码不对 
            return Promise.reject({
                code: 100,
                status,
                statusText
            });
        }
        //转换如果失败,走到catch,转换成功走下一个THEN
        return response.json().catch(resone => {
            return Promise.reject({
                code: 200,
                message: resone.message
            });
        });

    })
    .then(value => {
        console.log('成功', value);
    })
    .catch(resone => {
        //状态码不是2开始的[code=100],转换响应主体格式失败[code=200],请求中断[code=20],断网
        let { code, status } = resone || {};
        if (code === 100) {
            switch (+status) {
                case 404:
                    Message.error('请求地址错误');
                //...
            }
        } else if (code === 200) {
            Message.error('请求格式转换失败');
        } else if (code === 20) {
            Message.error('请求中断');
        } else {
            Message.error('网路出现异常');
        }
    });
//中断请求
// controller.abort();
举报

相关推荐

0 条评论