HTTP请求的GET,DELETE请求能有body吗?
昨天上班的时候后端有一个delete请求,要求我把参数放在url的query string上面。于是我说其实可以放在请求的实体中,但是后端说delete和get是没有请求实体的。这和我的记忆不太一样。那么到底delete和post请求能有实体吗?先看网上的资料先通过简单的搜索在stack overflow找到一个类似的问题, Is an entity body allowed for an HTT
昨天上班的时候后端有一个delete
请求,要求我把参数放在url
的query string
上面。于是我说其实可以放在请求的实体中,但是后端说delete
和get
是没有请求实体的。这和我的记忆不太一样。那么到底delete
和post
请求能有实体吗?
先看网上的资料
先通过简单的搜索在stack overflow找到一个类似的问题, Is an entity body allowed for an HTTP DELETE request?。回答中说到并没有禁止和不推荐在get
和delete
方法中使用实体。意思就是说其实是可以使用的。那么再看回答中给出的规范的资料,确实http规范中并没有说明有任何方法不能使用
实体。
继续探究
但是有时候现实生活往往和规范不一致。所以我们还要试验一下,首先是我们先用node
搭建一个服务器,打印收到的实体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const http = require('http'); http.createServer((req, res) => { const { method, url } = req; console.log(`METHOD: ${method}`); console.log(`URL:${url}`); const body = []; req .on('data', (chunk) => { body.push(chunk) }) .on('end', () => { let bodyString = Buffer.concat(body).toString(); console.log(`BODY: ${body}`) res.end(bodyString || 'body is empty'); }); }).listen(3000); |
在浏览器中使用ajax测试
get请求
在浏览器中打开localhost:300
页面,并且在控制台执行以下代码:
1 2 3 4 5 | (function() { const ajax = new XMLHttpRequest(); ajax.open('get', 'http://localhost:3000?qs=qs'); ajax.send('name=bob'); })() |
服务器打印:
1 2 3 | METHOD: GET URL:/?qs=qs BODY: |
没有接收到body
delete请求
delete
请求:
在浏览器中打开localhost:300
页面,并且在控制台执行以下代码:
1 2 3 4 5 | (function() { const ajax = new XMLHttpRequest(); ajax.open('delete', 'http://localhost:3000?qs=qs'); ajax.send('name=bob'); })() |
服务器打印:
1 2 3 | METHOD: DELETE URL:/?qs=qs BODY: name=bob |
接收到body
使用curl命令测试
get请求
命令行中执行下面的命令:
1 | curl -X GET -d 'name=bob' localhost:3000 |
服务器打印:
1 2 3 | METHOD: GET URL:/ BODY: name=bob |
接收到body
delete请求
1 | curl -X DELETE -d 'name=bob' localhost:3000 |
服务器打印:
1 2 3 | METHOD: DELETE URL:/ BODY: name=bob |
接收到body
发现curl
命令的body都是可以正常发送,但是浏览器中的ajax却不行这是为什么呢?查看XMLHttpRequest
规范发现:
The send(body) method must run these steps:
1. If state is not opened, then throw an "InvalidStateError" DOMException. 2. If the send() flag is set, then throw an "InvalidStateError" DOMException. 3. If the request method is GET or HEAD, set body to null. 4. If body is not null, then: 5. ....
原来XMLHttpRequest
规范定义method时get或者head的时候,XMLHttpRequest会忽略body。所以会产生前面实验的现象。
那么这些请求到底有什么不一样呢
其实从http报文的角度看,他们完全都是一样的。没有任何区别,大家能发送的信息都是一样的。你能做的我也能做,不一样的在于method
所代表的这个请求的语义。
结论
最后总结一下,在http规范任何方法都能发送请求实体。他们报文时没有任何区别的,但是在浏览器中,因为XMLHttpRequest
规范的限制,浏览器中ajax发送的http请求,get
,delete
请求不能携带实体。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)