HTTP请求的GET,DELETE请求能有body吗?

探讨HTTP DELETE和GET请求是否能携带实体数据,通过实验对比浏览器AJAX和curl命令行工具的差异,揭示XMLHttpRequest规范对GET和DELETE请求的限制。

昨天上班的时候后端有一个delete请求,要求我把参数放在urlquery string上面。于是我说其实可以放在请求的实体中,但是后端说deleteget是没有请求实体的。这和我的记忆不太一样。那么到底deletepost请求能有实体吗?

先看网上的资料

先通过简单的搜索在stack overflow找到一个类似的问题, Is an entity body allowed for an HTTP DELETE request?。回答中说到并没有禁止和不推荐在getdelete方法中使用实体。意思就是说其实是可以使用的。那么再看回答中给出的规范的资料,确实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请求,getdelete请求不能携带实体。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值