从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沟通的。
于是我仔细对比了两次请求的不同。
二者的
Content-Type
是不同的,我们可以看到fetch
请求,因为我没有在请求头里定义类型,所以当前是text/plain
,即普通文本类型。为什么jquery发出的却是application/x-www-form-urlencoded
呢?...那当然是因为jq的ajax方法自带默认配置啊...(其实也可能是因为
XMLHttpRequest
对象发送POST请求有默认的Content-Type
配置,已确认并未配置。)
jquery源码
所以application/x-www-form-urlencoded
到底是一种什么样的类型呢?
可以看到我们发送的数据挺好的...
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-data
和text/plain(HTML5)
。 - multipart/form-data
用于发送文件等二进制数据。
- application/json
- text/xml
参考资料:
四种常见的 POST 提交数据方式