zoukankan      html  css  js  c++  java
  • 话说Fetch这个API

    前言:

    最近在研究React这个框架,成功的成为了一名新的入坑着。用过React的都知道React的强大主要是在于它的生态的强大,React说的再大不过也就是一个UI框架罢了。不过我们学习react也主要因为这个生态,有facebook支持,质量相对有保障,衍生出的react-native, react-canvas等轮子在很多场景下可以直接拿来用。碎片化是React当前的状态,比如flux库,promise库,utils函数库,dom操作库,ajax库等等,每个点都有2-3个库在开源社区处于竞争状态,各有所长,大家根据自身的需要去选择。而我打算用Fetch作为ajax库来摆脱jquery这个千年不变的大杀器。

    Fetch介绍

    我们一提到局部刷新,前后端交互,异步加载等首先想到的ajax,好像在我们的认知中除了ajax就没有别的了。其实我们都被这种观念误导了,ajax只是对于XMLHttpRequest的一种封装,我们谈及Ajax技术的时候,通常意思就是基于XMLHttpRequest的Ajax,它是一种能够有效改进页面通信的技术。而Fetch API则是XMLHttpRequest的最新替代技术, 它是W3C的正式标准。

    Fetch的使用

    下面我们看一下Fetch的兼容性

    Fetch的兼容性

    总体来说,最新的浏览器都开始慢慢的兼容它了,但是想让它独立的用于前端项目还是任重而道远啊。。。

    如果你想独立在前端项目中兼容Fetch,可以考虑看这篇文章使用fetch遇到过的坑但是我不推荐去自己部署Fetch。

    我是在React项目中了解到Fetch的,使用的包是:whatwg-fetch

    Fetch的优点

    前面说了那么多,身为吃瓜群众的我们就是好奇:那他有什么优点能让颠覆了整个前端行业的ajax退位让贤呢?

    XMLHttpRequest 是一个设计粗糙的 API,不符合关注分离(Separation of Concerns)的原则,配置和调用方式非常混乱,而且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。

    Fetch 的出现就是为了解决 XHR 的问题,拿例子说明:

    使用 XHR 发送一个 json 请求一般是这样:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'json';
    
    xhr.onload = function() {
      console.log(xhr.response);
    };
    
    xhr.onerror = function() {
      console.log("Oops, error");
    };
    
    xhr.send();
    

    使用 Fetch 后,顿时看起来好一点(其实jquery的ajax也实现了Promise)

    fetch(url).then(function(response) {
      return response.json();
    }).then(function(data) {
      console.log(data);
    }).catch(function(e) {
      console.log("Oops, error");
    });
    

    使用 ES6 的 箭头函数 后:

    fetch(url).then(response => response.json())
      .then(data => console.log(data))
      .catch(e => console.log("Oops, error", e))
    

    现在看起来好很多了,但这种 Promise 的写法还是有 Callback 的影子,而且 promise 使用 catch 方法来进行错误处理的方式有点奇怪。不用急,下面使用 async/await 来做最终优化:

    注:async/await 是非常新的 API,属于 ES7,目前尚在 Stage 1(提议) 阶段,这是它的完整规范。使用 Babel 开启 runtime 模式后可以把 async/await 无痛编译成 ES5 代码。也可以直接使用 regenerator 来编译到 ES5。

    try {
      let response = await fetch(url);
      let data = await response.json();
      console.log(data);
    } catch(e) {
      console.log("Oops, error", e);
    }
    // 注:这段代码如果想运行,外面需要包一个 async function
    

    duang~ 的一声,使用 await 后,写异步代码就像写同步代码一样爽。await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try...catch 捕获。

    Promise,generator/yield,await/async 都是现在和未来 JS 解决异步的标准做法,可以完美搭配使用。这也是使用标准 Promise 一大好处。最近也把项目中使用第三方 Promise 库的代码全部转成标准 Promise,为以后全面
    使用 async/await 做准备。

    以上资料来自 传统 Ajax 已死,Fetch 永生

    但是我认为Fetch最不同于ajax的是让我们对于请求头的设置更加方便,更加灵活。

    Fetch中的API

    对于传统的XMLHttpRequest而言,你必须使用它的一个实例来执行请求和检索返回的响应。 但是通过Fetch API,我们还能够明确的配置请求对象。你可以通过Request构造器函数创建一个新的请求对象,这也是建议标准的一部分。 第一个参数是请求的URL,第二个参数是一个选项对象,用于配置请求。请求对象一旦创建了, 你便可以将所创建 的对象传递给fetch()方法,用于替代默认的URL字符串。示例代码如下:

    var req = new Request(URL, {method: 'GET', cache: 'reload'});
    fetch(req).then(function(response) {
      return response.json();
    }).then(function(json) {
      insertPhotos(json);
    });
    

    上面的代码中我们指明了请求使用的方法为GET,并且指定不缓存响应的结果。

    有关Request对象的另一件更酷的事在于,你还可以基于原有的对象创建一个新的对象。 新的请求和旧的并没有什么不同,但你可以通过稍微调整配置对象,将其用于不同的场景。 例如,你可以基于原有的GET请求创建一个POST请求,它们具有相同的请求源。代码如下:

    
     // 基于req对象创建新的postReq对象
      var postReq = new Request(req, {method: 'POST'});
    

    每个Request对象都有一个header属性,在Fetch API中它对应了一个Headers对象。 通过Headers对象,你能够修改请求头。不仅如此,对于返回的响应,你还能轻松的返回响应头中的各个属性。 但是需要注意的是,响应头是只读的。

    var headers = new Headers();
    headers.append('Accept', 'application/json');
    var request = new Request(URL, {headers: headers});
    
    fetch(request).then(function(response) {
        console.log(response.headers);
    });
    

    在上面的代码中,你可以通过Headers构造器来获取这个对象,用于为新的Request对象配置请求头。

    相似的,你可以创建一个Response对象:

    function responseDemo() {
        var headers = new Headers({
            'Content-Type': 'application/json',
            'Cache-Control': 'max-age=3600'
        });
    
        var response = new Response(
            JSON.stringify({photos: {photo: []}}),
                {status: 200, headers: headers}
        );
        response.json().then(function(json) {
            insertPhotos(json);
        });
    }
    

    Request和Response都完全遵循HTTP标准。
    以上资料来自 深入浅出Fetch API

    最后再说点

    其实整合这篇文章毛目的没有,就是因为注意用post提交数据时记得设置'Content-Type'为'application/x-www-form-urlencoded; charset=UTF-8'

  • 相关阅读:
    angular学习笔记(二十五)-$http(3)-转换请求和响应格式
    angular学习笔记(二十四)-$http(2)-设置http请求头
    angular学习笔记(二十三)-$http(1)-api
    Replace 在动态sql中的实现
    SQL 中 replace 替换字符串中的字符 ''
    sqlserver 时间字符串转化为时间格式
    update set where exists 多表更新 在mssql、MySQL、Oracle中分别用法
    LPAD在Oracle中和 mssql以及在MySQL中的不同用法 以及调用存储过程方法
    支付宝对账单下载Java正式商户调用
    支付宝对账单下载Java沙箱调用
  • 原文地址:https://www.cnblogs.com/jingh/p/6290436.html
Copyright © 2011-2022 走看看