一文告知HTTP GET是否可以有请求体

HTTP GET是否可以有请求体

先说结论:
HTTP协议没有规定GET请求不能携带请求体,但是部分浏览器会不支持,因此不建议GET请求携带请求体。

  • HTTP 协议没有为 GET 请求的 body 赋予语义,也就是即不要求也不禁止 GET 请求带 body。
  • 大多数 HTTP 实现从技术上都支持 HTTP GET 请求带 body,少数实现会禁止(google-chrome 浏览器、node-fetch),少数实现会不建议(Fiddler)。

1 HTTP协议对GET请求包含BODY的规定

1.1 RC1945

RFC 1945 发布于 1996 年,描述了 HTTP/1.0 。

其中和 body 有关的第 7 节提到了一下内容:

Full-Request and Full-Response messages may transfer an entity within some requests and responses. An entity consists of Entity-Header fields and (usually) an Entity-Body.
译:Full-Request 和 Full-Response 消息可以在某些请求和响应中传输实体。实体包括实体首部字段,并且通常包括一个实体 body。

说明 HTTP/1.0 会通过请求或响应的 body 传输实体,并且没有限定哪些请求方法不能传输实体。也就是说 GET 也可以有 body。

另外其 8.1 节关于 GET 和 POST 方法有如下描述:

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
译:GET 方法表示查询由 Request-URI 标识的任何信息(形式为实体)。
The POST method is used to request that the destination server accept the entity enclosed in the request …
译:POST 方法用于请求目标服务器接受包含在请求中的实体 …

说明 GET 方法的语义是请求实体,POST 方法的语义是提交实体,两者有明确的分工。

RFC 1945 这两处的内容可以提炼出两条信息:

  1. 请求或响应需要传输实体时才会有 body。
  2. GET 请求用于请求实体,而不是传输实体。
    根据这两条信息可以推出,GET 请求没有传输实体的语义,自然也不需要 body。但 RFC 1945 也没有明确规定 GET 请求不能传输实体、不能有 body。所以按 HTML 1.0 规范,GET 请求是可以有 body 的,只不过没有为其定义语义。

1.2 RFC 2068

RFC 2068 发布于 1997 年,描述了 HTTP/1.1。

RFC 2068 是对 RFC 1945 的更新,在 4.3 节有以下描述:

A message-body MAY be included in a request only when the request method allows an entity-body.
译:只有当请求方法允许使用实体 body 时,请求中才可以包含消息 body。

第 9 节是关于各个 HTTP 请求方法的描述,但只有第 9.8 节提到:

A TRACE request MUST NOT include an entity.
译:TRACE 请求必须不能包含实体。

另外,对 PUT、POST 的描述都默认有实体。但是对 GET 描述并没有提到请求中是否能包含实体 body。

也就是说 TRACE 不允许包含 body,PUT、POST 请求包含 body,但是 GET 没有明确说明,这种没说明的情况到底是允许还是不允许呢?

1.3 RFC 2616

RFC 2616 发布于 1999 年,是对 RFC 2068 的更新,还是描述的 HTTP/1.1。

其 4.3 节增加了如下描述:

A message-body MUST NOT be included in a request if the specification of the request method does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
译:如果本规范规定了某个请求方法不允许发送实体,则绝不能在请求中包含消息 body。服务器应该读取和转发任何请求的消息体(body);如果某个请求方法没有定义实体语义,那么在处理请求时应该忽略消息体(body)。

但第 9 节对于各个方法的描述中还是没有说 GET 请求是否能有 body。

1.4 RFC 7231

2004 年发布的 RFC 7230~7235 是对 RFC 2626 的修订。其中 RFC 7231 是 HTTP 的“核心”语义规范,终于在 4.3.1 节明确提到了 GET 请求的 body:

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
译:GET 请求消息中的有效负载(即 body)没有定义的语义;在 GET 请求上发送有效负载主体可能会导致某些现有实现拒绝该请求。

说明修订规范的人也知道有的 HTTP server 实现会拒绝带有 body 的 HTTP GET 请求。但是为什么规范迭代了这么多次都不规定每个请求方法是否能包含 body 呢?留下这么大的争议空间也是醉了。

2 现有实现对 GET 请求 body 的支持

请求库/工具是否支持GET带body
XMLHttpRequest不支持
Fetch不支持
Requests(Python最流行的HTTP请求库)支持
HTTPX(Python库)支持
axios(基于Promise的HTTPClient库)支持
superagent支持
node-fetch(Node.js的一个HTTP请求库)不支持
curl支持
Postman支持
Apifox支持
Fiddler支持,但是会用红色告警
nginx支持
FastAPI支持
  • Fildder发送GET请求红色警告⚠️图:

在这里插入图片描述

3 结论

🚀HTTP协议中没有明确规定GET请求是否能带body,市场上部分浏览器会不支持GET请求带body。

软件工程中有一条原则:不要依赖未定义的行为。HTTP 协议未定义 GET 请求的 body 语义,如果想用 GET 请求发送 body,得先为其定义语义,并确保上下游都能很好的支持。作为服务接口的提供方,不应该假设所有的调用方都能发出 GET 请求 body;作为调用方,不应该假设服务方能完美解析 GET 请求 body,但如果服务方提供了支持 GET 请求 body 的接口,可以放心使用,不用纠结。

软件工程中还有另一条原则,不记得原文了,翻译成中国的老话就是:严于律己,宽已待人。我们在写库、写框架、写工具时应该支持 GET 请求带 body;在封装接口时,尽量不要强制调用方用 GET body 提交数据,除非遇到用 GET body 才符合逻辑的特殊情况;在使用别人提供的库、框架、工具,或者调用协作方提供的接口时不应该强求对方支持 GET 请求 body。

参考文章:
https://zhuanlan.zhihu.com/p/456921996

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/103669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Idea集成Docker

1、前言 上一节中,我们介绍了Dockerfile的方式构建自己的镜像。但是在实际开发过程中,一般都会和开发工具直接集成,如Idea。今天就介绍下idea和Docker如何集成。 2、开启docker远程 要集成之前,需要我们本机能够访问docker服务…

基于LoRa的远程气象站:实现远程气象监测与数据传输

随着物联网技术的不断发展,基于无线通信的远程气象监测系统得以广泛应用。本文将介绍一种基于LoRa技术的远程气象站,通过LoRa模块实现气象数据的远程采集和传输,为气象监测提供了一种高效、低功耗的解决方案。 LoRa技术概述 LoRa&#xff08…

ssm+vue的课程网络学习平台管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频: ssmvue的课程网络学习平台管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层体…

《从程序员到架构师》:从现在开始培养架构思维,一点都不晚

《从程序员到架构师》:从现在开始培养架构思维,一点都不晚 尽管大家都明白软件架构非常重要,但是能够真正理解并应用软件架构的核心思维去解决实战的商业项目,确实大多数程序员所欠缺的。本文将从一个全新的视角,重新带…

【算法练习Day19】二叉搜索树的最近公共祖先二叉搜索树中的插入操作删除二叉搜索树中的节点

​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 二叉搜索树的最近公共祖先叉…

Avalonia常用小控件Svg

1.项目下载地址:https://gitee.com/confusedkitten/avalonia-demo 2.UI库Semi.Avalonia,项目地址 https://github.com/irihitech/Semi.Avalonia 3.SVG库,Avalonia.Svg.Skia,项目地址 https://github.com/wieslawsoltes/Svg.Ski…

【数据库——MySQL(实战项目1)】(4)图书借阅系统——触发器

目录 1. 简述2. 功能代码2.1 创建两个触发器,分别在借出或归还图书时,修改借阅人表中的已借数目(附加:借阅人表的总借书数、图书表的借阅次数以及更新图书表的图书状态为(已借出/在架上))字段;2.2 创建触发器,当借阅者…

redis 哨兵 sentinel(一)配置

sentinel巡查监控后台master主机是否故障,如果故障根据投票数自动将某一个从库转换为新主库,继续对外服务 sentinel 哨兵的功能 监控 监控主从redis库运行是否正常消息通知 哨兵可以将故障转移的结果发送给客户端故障转移 如果master异常,则…

IOS17 轻松签全能签还能不能用?多开能否使用?升级后微信底栏消失怎么办?BY:后厂村路灯

从iphone15还没出就有小伙伴们追着问, 到现在也有人一直再问iOS17能不能用,看来换手机的人很多呀。 这里统一回答一下:“iOS17苹果签名可以用,多开也可以用”但是还是有些地方注意。 如果你是16系统直接升级刀17就可以&#xff…

使用 Splashtop 驾驭未来媒体和娱乐

在当今时代,数字转型不再是可选项,而是必选项。如今,媒体与娱乐业处于关键时刻,正在错综复杂的创意、技术和远程协作迷宫之中摸索前进。过去几年发生的全球事件影响了我们的日常生活,不可逆转地改变了行业的运作方式&a…

给你一个项目,你将如何开展性能测试工作?

一、性能三连问 1、何时进行性能测试? 性能测试的工作是基于系统功能已经完备或者已经趋于完备之上的,在功能还不够完备的情况下没有多大的意义。因为后期功能完善上会对系统的性能有影响,过早进入性能测试会出现测试结果不准确、浪费测试资…

【C++STL基础入门】list基本使用

文章目录 前言一、list简介1.1 list是什么1.2 list的头文件 二、list2.1 定义对象2.2 list构造函数2.3 list的属性函数 总结 前言 STL(Standard Template Library)是C标准库的一个重要组成部分,提供了一套丰富的数据结构和算法,可…

【Lombok的Bug记录】前端传的有值,但是到后端就全为空了

项目场景: 项目背景:使用Data注解标注类 问题描述 前端传的有值,但是到后端就全为空了 原因分析: AName和aName生成的set方法名是一样的,所以换名字就行了! 解决方案: 属性不要写成xXxx的形式…

【伪彩色图像处理】将灰度图像转换为彩色图像研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

YB4014是可以对单节磷酸铁锂电池进行恒流/恒压充电管理的集成电路。

概述: YB4014是可以对单节磷酸铁锂电池进行恒流/恒 压充电管理的集成电路。该器件内部包括功率晶 体管,不需要外部的电流检测电阻和阻流二极管 YB4014只需要极少的外围元器件,非常适合于 便携式应用的领域。热调制电路可以在器件的功 耗比较大…

flutter开发入门,windows环境安装,耗时一天解决各种bug,终于成功

首先说明要安装的环境:java8必须,android studio,chrome是开发安卓和web是必须的 java8的下载地址:https://www.java.com/en/download/、 java8蓝奏云下载地址:jre-8u381-windows-x64.exe - 蓝奏云 flutter国内环境…

Spring Boot 中的 Redis 数据操作配置和使用

Spring Boot 中的 Redis 数据操作配置和使用 Redis(Remote Dictionary Server)是一种高性能的开源内存数据库,用于缓存、消息队列、会话管理和数据存储。在Spring Boot应用程序中,Redis被广泛用于各种用例,包括缓存、…

下载安装Ipa Guard

下载安装Ipa Guard 可以前往ipaguard工具官网下载,工具是免费下载,免费体验使用的。下载地址是https://www.ipaguard.com。 下载后解压工具便ok了,工具是绿色软件,无需其他安装流程。双击Ipa Guard.exe 启动ipaguard。 ipaguard…

Java语法基础案例(二)

目录 案例六:抢红包 案例七:找素数 方法一: 方法二: 方法三: 案例八:实现双色球 关于本项目所用所有方法的解释: 案例六:抢红包 一个大V直播时发起了抢红包活动,分…

2023年中国固废处理行业研究报告

第一章 行业概况 1.1 定义 固体废物处理是一个日益重要的领域,随着中国城市化进程的加速和工业产值的持续增长,固体废物的产生量也在不断上升。根据《固体废物污染环境防治法》的定义,固体废物包括了人类在生产、生活和其他活动中产生的固态…