- A+
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
1、背景
与后端对接口时,看到有一个get
请求的接口,它的参数是放在body
中的
******get
请求参数可以放在body
中??
随即问了后端,后端大哥说在postman上是可以的,还给我看了截图
可我传参怎么也调不通!
下面就来探究到底是怎么回事
2、能否发送带有body参数的get请求
项目中使用axios
来进行http
请求,使用get
请求传参的基本姿势:
// 参数拼接在url上 axios.get(url, { params: {} })
如果想要将参数放在body
中,应该怎么做呢?
查看axios的文档并没有看到对应说明,去github上翻看下axios源码看看
在lib/core/Axios.js
文件中
可以看到像delete
、get
、head
、options
方法,它们只接收两个参数,不过在config
中有一个data
熟悉的post
请求,它接收的第二个参数data
就是放在body
的,然后一起作为给this.request
作为参数
所以看样子get
请求应该可以在第二个参数添加data
属性,它会等同于post
请求的data
参数
顺着源码,再看看lib/adapters/xhr.js
,上面的this.request
最终会调用这个文件封装的XMLHttpRequest
export default isXHRAdapterSupported && function (config) { return new Promise(function dispatchXhrRequest(resolve, reject) { let requestData = config.data // 将config.params拼接在url上 request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); // 省略若干代码 ... // Send the request request.send(requestData || null); }); }
最终会将data
数据发送出去
所以只要我们传递了data
数据,其实axios
会将其放在body
发送出去的
2.1 实战
本地起一个koa
服务,弄一个简单的接口,看看后端能否接收到get
请求的body
参数
router.get('/api/json', async (ctx, next) => { console.log('get请求获取body: ', ctx.request.body) ctx.body = ctx.request.body }) router.post('/api/json', async (ctx, next) => { console.log('post请求获取body: ', ctx.request.body) ctx.body = ctx.request.body })
为了更好地比较,分别弄了一个get
和post
接口
前端调用接口:
const res = await axios.get('/api/json', { data: { id: 1, type: 'GET' } }) const res = await axios.post('/api/json', { data: { id: 2, type: 'POST' } }) console.log('res--> ', res)
在axios
的send
处打一个断点
可以看到数据已经被放到body中了
后端已经接收到请求了,但是get
请求无法获取到body
!
结论:
- 前端可以发送带
body
参数的get
请求,但是后端接收不到 - 这就是接口一直调不通的原因
3、这是为何呢?
我们查看WHATGW
标准,在XMLHttpRequest
中有这么一个说明:
大概意思:如果请求方法是GET
或HEAD
,那么body
会被忽略的
所以我们虽然传递了,但是会被浏览器给忽略掉
这也是为什么使用postman
可以正常请求,但是前端调不通的原因了
因为postman
并没有遵循WHATWG
的标准,body
参数没有被忽略
3.1 fetch
是否可以?
fetch.spec.whatwg.org/#request-cl…
答案:也不可以,fetch
会直接报错
总结
- 结论:浏览器并不支持
get
请求将参数放在body
中 XMLHTTPRequest
会忽略body
参数,而fetch
则会直接报错