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

2017-07-07  本文已影响0人  anshi

作为前端出身的,码农,没有深入了解过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数据类型。

multipart/form-data类型的请求

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

上一篇下一篇

猜你喜欢

热点阅读