基于fetch的Http封装

758 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

1, 简介

Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。fetch 不会发送跨域 cookies,除非你使用了 credentials 的属性,fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象, 官网给出的Demo,可参考:

async function postData(url = '', data = {}) {
  // Default options are marked with *
  const response = await fetch(url, {
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

postData('https://example.com/answer', { answer: 42 })
  .then(data => {
    console.log(data); // JSON data parsed by `data.json()` call
  });

2, 在线API接口

在开始之前,先介绍三个我认为线上使用比较方便的mock接口地址, 在平常的开发测试,练习中使用,确实很方便。

(1) cnode : cnodejs.org/api

常用的get请求,post请求都满足。只需要接口和API拼接接口:

# 主题页获取(get请求)
const url = " https://cnodejs.org/api/v1/topics "

# 标记全部已读 (post请求)
const url = " https://cnodejs.org/api/v1/message/mark_all"

最简单的测试方法:postman跑一下就可得到结果

1643014418547.png

(2)api-github: api.github.com/

1643016463600.png (3)Fast Mock: www.fastmock.site/#/projects

区别cnode: 我们可以自定义接口名称,接口请求方式,已经接口mock的数据格式。

操作步骤: 注册登录 Fast Mock网址

1, 新建项目之后,新增接口,

1643015170034.png (2) 点击保存之后

1643015205500.png

(3) 点击复制完整接口

1643015257440.png

(4)打开postman, 测试接口

1643015295898.png

接下来我们针对Http进行封装,测试采用Fast Mock接口进行验证

3, HTTP封装

新建http.js

/**
 *@description Http请求封装
 */

const mergeOptions = (defaultOptions = {}, options = {}) => {
  const headers = Object.assign({}, defaultOptions.headers, options.headers);
  return Object.assign({}, defaultOptions, options, { headers })
}
class Http {
   /**
    *@description get请求
    * @param {*} url
    * @param {*} options
    */
   static async get(url, options) {
     // 定义默认请求头参数
     const defaultOptions = {
        headers: {
          "Token": "Authtion"
        },
        mode: 'cors',
        credentials: 'omit'
     }
     // 如果需要额外拼接请求头信息,根据条件进行添加
    if (true) {
      Object.assign(defaultOptions.headers, {
        "AUTH-TOkKEN": "AUTH-TOkKEN"
      })
    }
     const response = await fetch(url, mergeOptions(defaultOptions, options))
     return response.json()
   }
   /**
    *@description post请求
    * @param {*} url
    * @param {*} [data={}]
    * @param {*} options
    * @return {*} 
    */
   static async post(url, data = {}, options) {
     const defaultOptions = {
       headers: {
        "Content-Type": "application/json;charset=UTF-8"
       },
       method: "post",
       body: JSON.stringify(data),
       mode: "cors",
       credentials: 'omit'
     };
    // 如果需要额外拼接请求头信息,根据条件进行添加
    if (true) {
      Object.assign(defaultOptions.headers, {
        "AUTH-TOkKEN": "AUTH-TOkKEN"
      })
    }
    const response = await fetch(url, mergeOptions(defaultOptions, options));
    return response.json()
   }
   /**
    * @description put请求
    * @static
    * @param {*} url
    * @param {*} [data={}]
    * @param {*} options
    * @return {*} 
    */
   static async put(url, data = {}, options) {
    const defaultOptions = {
      headers: {
       "Content-Type": "application/json"
      },
      method: "put",
      body: JSON.stringify(data),
      mode: "cors",
      credentials: 'omit'
    };
    // 如果需要额外拼接请求头信息,根据条件进行添加
    if (true) {
      Object.assign(defaultOptions.headers, {
        "AUTH-TOkKEN": "AUTH-TOkKEN"
      })
    }
    const response = await fetch(url, mergeOptions(defaultOptions, options))
    return response.json()
   }
}

4, 接口测试

新建index.html页面;

注意: 在html页面中使用import引入js, 需要设置script中的type=“module"

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Http封装</title>
 </head>
<body>
  <script type="module">
    import { Http } from './http.js'
    async function getData() {
       const response = await Http.get('https://www.fastmock.site/mock/9603b7fde737fe866758932146a846a5/react/api/testApi')
       const { code , data } = response
       console.log(data)
    }
    async function postData() {
       const response = await Http.post('https://www.fastmock.site/mock/9603b7fde737fe866758932146a846a5/react/api/postTest')
       const { code , data } = response
       console.log(data)
    }
    const btnG = document.getElementById("btnGet");
        btnG.onclick = function () {
          getData()
        }
    const btnP = document.querySelector("#btnPost")
        btnP.onclick = function () {
           postData()
        }
  </script>
   <button id="btnGet" >get请求测试</button>
   <button id="btnPost">post请求测试</button>
</body>
</html>

效果如下图:

1643031515504.png