美文网首页
从jQuery.ajax到fetch,你还差一本HTTP权威指南

从jQuery.ajax到fetch,你还差一本HTTP权威指南

作者: anshi | 来源:发表于2017-07-07 17:57 被阅读0次

    作为前端出身的,码农,没有深入了解过HTTP,一直以来靠抹平XMLHttpRequest种种细节的jq发送http请求,直到有一天我想用fetch的时候...遇到了许多莫名的问题。这些问题就好象是你想学vue的时,折腾半天webpack;想写ES6时,折腾半天babel配置;想学node时,不知无从下手。我想这种情况,或许只有非CS出身前端出身的程序员才会理解吧。

    有一天我发送了这么一个请求(不要问我为什么查询用POST方法)

    let _this = this;
    let data = {
      pageIndex: 1,
      pageSize: 20,
      key: getParam('key'),
      cid: getParam('cid'),
      sortKey:'new'
    };
    $.ajax({
      type: 'POST',
      url: `${api}/search/search.do`,
      data: data,
      success(json){
        if (json.code === 1000) {
          _this.items = json.data;
        }
      }
    })
    

    一切正常...然后我改成fetch发送吧。

    fetch(`${api}/search/search.do`, {
      method: "POST",
      body: JSON.stringify(data)
    })
    .then(response => {
      if (response.ok === true) {
        return response.json();
      }
    })
    .then(json => {
      if (json.code === 1000) {
        _this.items = json.data;
      }
    })
    .catch(err => {
      console.log('getJson error' + err)
    })
    

    是的...我以为全世界大多数请求都是用json沟通的。
    于是我仔细对比了两次请求的不同。

    fetch jquery
    二者的 Content-Type是不同的,我们可以看到fetch请求,因为我没有在请求头里定义类型,所以当前是text/plain,即普通文本类型。为什么jquery发出的却是application/x-www-form-urlencoded呢?
    ...那当然是因为jq的ajax方法自带默认配置啊...(其实也可能是因为XMLHttpRequest对象发送POST请求有默认的Content-Type配置,已确认并未配置。) jquery源码

    所以application/x-www-form-urlencoded到底是一种什么样的类型呢?

    jquery发送的数据

    可以看到我们发送的数据挺好的...

    fetch发送的数据
    但是对比点击 view source后的结果可以看出,fetch发出的是json格式,而jq发出的请求是这样的 jq请求 view source
    再仔细看它的类型application/x-www-form-urlencoded,前面先不管... urlencoded,我们知道js提供encodeURI方法,用于将完整的URI转义。所以这一串数据,应该是 encodeURI('pageIndex=1&pageSize=20&key=女装&cid=1&sortKey=new')返回的内容。
    回到我们最初的目的。用fetch做同样的事情...首先我们要把对象遍历成key=value的形式。
    我们写个转换的函数(未考虑深层对象的情况)
    function getUriEncodeParam(data) {
      let newArr = Object.keys(data);
      let param = '';
      newArr.forEach(function (item, idx) {
        if (idx === 0) {
          param += item + '=' + data[item];
        } else {
          param += '&' + item + '=' + data[item];
        }
      });
      return encodeURI(param);
    }
    
    //fetch
    fetch(`${api}/search/search.do`, {
      method: "POST",
      headers:{
        'content-type':'application/x-www-form-urlencoded; charset=UTF-8'
      },
      body: getUriEncodeParam(data)
    })
    

    成功响应,请求头部分也按照预期,响应的数据也正常了。
    同时也自惭形秽用jquery发请求那么多年(好像也有2年了...)似乎只关注url,data,回调但很少注意到请求头的一些东西...
    以下提几个常用的POST数据类型。

    • application/x-www-form-urlencoded
      浏览器原生的<form>表单,当 method属性值为 post 时, enctype属性可以定义提交给服务器的媒体类型,application/x-www-form-urlencoded是默认值。可取的值还有multipart/form-datatext/plain(HTML5)
    • multipart/form-data
      用于发送文件等二进制数据。
    multipart/form-data类型的请求
    • application/json
    • text/xml

    参考资料:
    四种常见的 POST 提交数据方式

    相关文章

      网友评论

          本文标题:从jQuery.ajax到fetch,你还差一本HTTP权威指南

          本文链接:https://www.haomeiwen.com/subject/yvelhxtx.html