• fetch简明学习


    前面的话

      Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取资源。本文将详细介绍fetch的相关内容

    概述

      跨网络异步获取资源的功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如 CORS和HTTP的扩展

      fetch 规范与 jQuery.ajax() 主要有两种方式的不同

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

      2、默认情况下, fetch 不会从服务端发送或接收任何 cookies,如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)

    fetch请求

      一个基本的 fetch请求设置起来很简单。这里我们通过网络获取一个图像并将其插入到一个 <img> 元素中。最简单的用法是只提供一个参数用来指明想fetch到的资源路径,然后返回一个包含响应结果的promise(一个 Response 对象)

    let myImage = document.querySelector('img');
    
    fetch('flowers.jpg')
    .then(function(response) {
        return response.blob();
    })
    .then(function(myBlob) {
        let objectURL = URL.createObjectURL(myBlob);
        myImage.src = objectURL;
    });

    自定义参数

      fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象:

    var myHeaders = new Headers();
    
    var myInit = { method: 'GET',
                   headers: myHeaders,
                   mode: 'cors',
                   cache: 'default' };
    
    fetch('flowers.jpg',myInit)
    .then(function(response) {
      return response.blob();
    })
    .then(function(myBlob) {
      var objectURL = URL.createObjectURL(myBlob);
      myImage.src = objectURL;
    });

    post

    // 通过fetch获取百度的错误提示页面
    fetch('https://www.baidu.com/search/error.html', {
        method: 'POST',
        body: JSON.stringify({a:1}),
       headers: { ...new Headers(headers), 'Content-Type': 'application/json' }
      })
      .then((res)=>{
        return res.text()
      })
      .then((res)=>{
        console.log(res)
      })

    JSON数据

    // 通过fetch获取百度的错误提示页面
    fetch('https://www.baidu.com/rec?platform=wise&ms=1&rset=rcmd&word=123&qid=11327900426705455986&rq=123&from=844b&baiduid=A1D0B88941B30028C375C79CE5AC2E5E%3AFG%3D1&tn=&clientWidth=375&t=1506826017369&r=8255', { // 在URL中写上传递的参数
        method: 'GET',
        headers: new Headers({
          'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON
        })
      })
      .then((res)=>{
        return res.json() // 返回一个Promise,可以解析成JSON
      })
      .then((res)=>{
        console.log(res) // 获取JSON数据
      })

    检测成功

      如果遇到网络故障,fetch() promise 将会 reject,带上一个 TypeError 对象。虽然这个情况经常是遇到了权限问题或类似问题——比如 404 不是一个网络故障。想要精确的判断 fetch() 是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true

    fetch('flowers.jpg').then(function(response) {
      if(response.ok) {
        response.blob().then(function(myBlob) {
          var objectURL = URL.createObjectURL(myBlob);
          myImage.src = objectURL;
        });
      } else {
        console.log('Network response was not ok.');
      }
    })
    .catch(function(error) {
      console.log('There has been a problem with your fetch operation: ' + error.message);
    });

    Headers

      使用 Headers 的接口,可以通过 Headers() 构造函数来创建一个自己的 headers 对象。一个 headers 对象是一个简单的多名值对:

    var content = "Hello World";
    var myHeaders = new Headers();
    myHeaders.append("Content-Type", "text/plain");
    myHeaders.append("Content-Length", content.length.toString());
    myHeaders.append("X-Custom-Header", "ProcessThisImmediately");

      也可以传一个多维数组或者对象字面量:

    myHeaders = new Headers({
      "Content-Type": "text/plain",
      "Content-Length": content.length.toString(),
      "X-Custom-Header": "ProcessThisImmediately",
    });

      它的内容可以被获取:

    console.log(myHeaders.has("Content-Type")); // true
    console.log(myHeaders.has("Set-Cookie")); // false
    myHeaders.set("Content-Type", "text/html");
    myHeaders.append("X-Custom-Header", "AnotherValue");
     
    console.log(myHeaders.get("Content-Length")); // 11
    console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
     
    myHeaders.delete("X-Custom-Header");
    console.log(myHeaders.getAll("X-Custom-Header")); // [ ]

    封装

      下面是笔者在react中对fetch的精简版封装

    import { showLoading, hideLoading, showAlertText, hideAlertText } from '@/components/Alert/module'
    import { logout } from '@/components/Auth/module'
    
    const async = ({ dispatch, url, method, data, headers, success, fail, doHideAlert }) => {
      // 显示loading
      dispatch(showLoading())
      let fetchObj = {}
      if (method) {
        fetchObj = {
          method,
          body: JSON.stringify(data),
          headers: new Headers({ ...headers, 'Content-Type': 'application/json' })
        }
      }
      fetch(url, fetchObj).then(res => {
        // 关闭loading
        dispatch(hideLoading())
        return res.json()
      }).then(json => {
        // 成功
        if (json.code === 0) {
          !doHideAlert && dispatch(showAlertText(json.message))
          setTimeout(() => {
            dispatch(hideAlertText())
          }, 1000)
          success && success(json.result)
          // 自定义错误
        } else if (json.code === 1) {
          dispatch(showAlertText(json.message))
          // 系统错误
        } else if (json.code === 2) {
          dispatch(showAlertText(json.message))
          fail && fail(json.err)
          // 认证失败
        } else if (json.code === 3) {
          dispatch(showAlertText(json.message))
          dispatch(logout)
        }
      }).catch(() => {
        dispatch(showAlertText('服务器故障'))
      })
    }
    
    export default async
  • 相关阅读:
    关于二进制的利用
    2017年浙江中医药大学程序设计竞赛 Solution
    2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest Solution
    2018-2019 ACM-ICPC, Asia Shenyang Regional Contest Solution
    2018-2019 ACM-ICPC, Asia Nanjing Regional Contest Solution
    AtCoder Grand Contest 029 Solution
    BZOJ 3307: 雨天的尾巴
    Codeforces Round #526 (Div. 2) Solution
    2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
    [HZNUOJ] 博
  • 原文地址:https://www.cnblogs.com/xiaohuochai/p/8677042.html
走看看 - 开发者的网上家园