zoukankan      html  css  js  c++  java
  • fetch详解

    window对象提供了一个fetch方法,用于实现基于promise的http请求。它取代了最早的XMLHttpRequest实现的ajax请求。

    1. 基本内容

    1. 基本语法

    fetch方法返回一个promise对象。

    const promise = fetch(url[, options]);

    url--发起请求的路径

    options--可选设置。可以设置method, headers, body等,method默认是"GET"。

    2. options配置对象

    1. 如果不设置options, method默认是GET方法。

    fetch(url)
    // 相当于
    fetch(url, {
       method: 'GET'
    })

    其传参通过url传参

    fetch(url+ 'a=1&b=2')

    2. 当请求方法为POST/PUT/DELETE等方法时,需要传请求体body和对应的headers

    const user = {name: "lyra"};
    fetch(url, {
       method: 'POST',
       body: {// 请求体
          user: JSON.stringify(user)
       },
        headers: {// 请求头
           Content-Type: "application/json;charset=utf-8"
        }
    })

    其中请求体body可以接受的参数类型有:

    • string  如:JSON格式, 其对应的请求头为application/json; charset=utf-8
    • FormData对象   对应的Content-Type:form/multipart
    • ArrayBuffer/ArrayBufferView/Blob  二进制
    • URLSearchParams对象   对应的Content-Type:application/x-www-form-urlencoded

    对于特殊的请求头,如application/json,需要手动进行设置。

        headers: {// 请求头
           Content-Type: "application/json;charset=utf-8"
        }

    如果需要传递cookie的凭证,但是又存在跨域问题,则应该设置:

    fetch(url, {
       // ⚠️ 此处的属性不是位于headers内部
        credentials: "include" // 相当于xhr.withCredentials = true
    })

    如果使用JWT的用户信息校验机制,则需要设置请求头

    fetch(url, {
        headers: {
           // jwtToken是用户登录后,服务端返回的结果;一般存在localStorage中
           authorization: `Bearer ${jwtToken}`
        }
    })

    2. 响应对象

    1. 获取响应对象response

    fetch请求的返回结果是promise内置的Response类的实例。该类提供了很多数据处理方法。

    获取response对象的方法有两种:

    /***考虑响应失败,即promise的reject状态**********
    1. 网络连接出现问题
    2. 请求网址不存在
    ****************************/
    
    //1. async..await
    try {
       const response = await fetch(url, options)
    }catch(e) {
       //当fetch的结果是reject
    }
    
    // 2. then
    fetch(url, options).then(response =>{
       // response为响应对象; 主要服务器有响应404, 500也属于resoloved状态
    }, () => {
        // reject状态
    })

    2. response的属性

    • response.ok   布尔值;状态码200-299时为true
    • reponse.status  http状态码
    • response.body  可读流; 可以实时计算数据的下载量
    // Step 1:启动 fetch 并赋值给 reader
    let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100');
    
    const reader = response.body.getReader();
    
    // Step 2:获取总长度(总块数)
    const contentLength = +response.headers.get('Content-Length');
    
    // Step 3:读取数据
    let receivedLength = 0; // 当前长度
    let chunks = []; // 存放接收到的二进制块的数组(包括 body)
    while(true) {
      const {done, value} = await reader.read();
    
      if (done) {
        break;
      }
    
      chunks.push(value);
      receivedLength += value.length;
    
      console.log(`Received ${receivedLength} of ${contentLength}`)
    }
    
    // Step 4:将块合并成单个 Uint8Array
    let chunksAll = new Uint8Array(receivedLength); // (4.1)
    let position = 0;
    for(let chunk of chunks) {
      chunksAll.set(chunk, position); // (4.2)
      position += chunk.length;
    }
    
    // Step 5:解码成字符串
    let result = new TextDecoder("utf-8").decode(chunksAll);
    
    // 我们完成啦!
    let commits = JSON.parse(result);
    alert(commits[0].author.login);
    • response.headers 响应头

    response.headers是一个类型Map类型的对象,可以通过get获取内容

    response.headers.get('Content-Type');
    // 迭代所有的headers
    for(let [key, value] of headers) {
       // key, value
    }

    3. response的方法

    用于获取对应类型的响应内容;其调用方法后的返回结果也是一个promise对象

    ⚠️下面解析请求体的方式只能使用一种;同时使用多种,只有第一个起作用。

    • response.json()  获取json对象
    • response.text()  获取文本
    • response.formData() 获取FromData对象
    • response.blob()
    • response.arraybuffer() 二进制形式

    数据处理的形式也有两种:

    // 1. async...await
    try {
        const response = await fetch(url, options);
        const data = await response.json();
    } catch (e) {
       // 
    }
    
    
    // 2. then
    fetch(url, options)
    .then(response => response.json()) .then(data => { //data }).catch(e= > { // })

    3. 简单封装

    封装后实现,GET和POST等方式的请求体传参形式相同。

    // GET方法需要将对象转为查询参数
    function obj2Str(obj) {
      let arr=[];
      for(let key in obj) {
        if (obj.hasOwnProperty(key)) {
          arr.push(`${key}=${obj[key]}`);
        }
      }
      return arr.join('&');
    }
    
    // 传递参数
    const data = {
      a: 1,
      b: 2
    }
    
    async function requset(url, objData, method='GET', headers) {  
      /**1,2只需要使用一个**/
      const defaultOptions = {
        // 1. 如果后台使用session验证用户信息
        "credentials": "include",// 相当于xhr.withCredentials = true,
      }
      const options = {
        ...defaultOptions, 
        method,
        headers: {
          // 2. 如果后台使用JWT验证用户信息
          "Authorization": `Bearer ${jwtToken}`,
          ...headers
        }
      };
      if (method === 'GET') {
        // GET方法通过URL传参
        url = `${url}?${obj2Str(objData)}`; 
      } else {
        options = {
          ...options,
          headers: {
            "Content-Type": "application/json; charset=utf-8",
            ...options.headers
          },
          body: JSON.stringify(data),  
        }
      }
      // 发起请求
      try {
        const response = await fetch(url, options);
        const data = await response.json();
        return data;
      } catch(e) {
        // 网络问题或者URL不存在
      }
    }
    
    function get(url, obj, headers) {
      return requset(url, obj, 'GET', headers);
    }
    
    function post(url, obj, headers) {
      return requset(url, obj, 'POST', headers);
    }
  • 相关阅读:
    TestNG之Factory
    Selenium2怎么调用selenium1中方法
    JAVA如何随机生成一个汉字
    selenium如何随机选取省份和城市的下拉框的值
    Bootstrap之登陆页面范例
    Bootstrap之信息记录
    Bootstrap之表格、表单应用
    Bootstrap之响应式导航栏
    Bootstrap之网格类
    使用fastjson将对象和字符串进行转换
  • 原文地址:https://www.cnblogs.com/lyraLee/p/12273941.html
Copyright © 2011-2022 走看看