我正在为我的一个项目开发一个REST API。我需要使用GET请求。我似乎不明白为什么使用url查询字符串上级body。这两种请求数据的方式之间有一些明显的区别--比如能够看到url中的参数,或者请求可以保存在浏览器的历史记录中。但是还有什么更重要的呢?用body请求数据是不好的吗?
o2rvlv0m1#
使用body并没有什么错。GET方法没有body并不是因为对body的使用有偏见。如果您看一下HTTP协议规范,您可能会有一些见解:“GET方法表示检索由Request-URI标识的任何信息(以实体的形式)。”简单地说,GET方法是为了只使用URI来获取某个资源而创建的,更简单地说,如果你只使用URI就可以获取某个资源,那么GET就是你应该使用的方法。事实上,您可以使用GET请求发送body,但它将被忽略(更多信息请访问:(第10页)如果出于任何原因需要传递主体,则需要使用不同的方法。POST是一个突出的示例:“POST方法用于请求源服务器接受包含在请求中的实体,作为由请求行中的请求URI标识的资源的新从属。”如果您正在使用REST API,我强烈建议您阅读HTTP规范https://www.rfc-editor.org/rfc/rfc2616
GET
POST
gfttwv5a2#
请求带正文的数据不好吗?是的,很糟糕。问题是,在HTTP中,GET方法被明确定义为不包含请求主体。GET请求消息中的有效负载没有定义的语义;在GET请求中发送有效载荷正文可能会导致一些现有的实现拒绝请求。-- RFC 7231这里的主要问题是,早期版本的HTTP规范在处理请求中的消息体时存在一些不明确的地方,实际上,将消息体放入GET请求是“未定义的行为”。工作组强烈希望确保该标准保持向后兼容。REST的部分 * 要点 * 是我们都使用一个公共标准,因此通用工具(浏览器、缓存、反向代理、蜘蛛...)适用于 * 每个人 * --或者更具体地说,适用于遵守该标准的每个人。对于GET,当您考虑缓存语义时,包含消息正文是没有意义的。HTTP中的缓存语义目前由RFC 7134定义,高级总结是target-uri是主缓存键;缓存只需要理解HTTP请求中的元数据就可以正确地完成它们的工作。如果我们要将语义应用于GET请求的主体,我们还需要以一种通用的方式定义这些语义如何影响缓存行为。例如,如果您设想一个查询场景(如GraphQL),响应中的预期表示取决于编码到请求主体中的信息。因此,现在您需要开始定义何时两个请求主体“相同”--白色是否重要?内容编码是否重要?如果主体被压缩会怎样?等等......对于不安全的请求(例如POST),我们不会遇到这样的问题,因为符合标准的缓存“必须”(MUST)写入不安全的请求。没有必要探究请求的消息体的表示,因为不存在内容会改变这一需求的情况。已经有人尝试为HTTP方法创建一个新的标准,这个标准是安全的 * 并且 * 包括一个消息体。在某种意义上,我们引入了一个新的方法令牌,并声明语义是安全的(以便我们可以执行抢先获取,并在不可靠的网络上重复请求),并且也许公共高速缓存不能存储响应,而是必须将每个请求转发给源服务器。也就是说,人们已经意识到差距有一段时间了,而且这个问题还没有一个标准化的解决方案--所以可能有一些困难的方面并不明显(除了采用与惰性的政治问题)。
2条答案
按热度按时间o2rvlv0m1#
使用body并没有什么错。
GET
方法没有body并不是因为对body的使用有偏见。如果您看一下HTTP协议规范,您可能会有一些见解:
“GET方法表示检索由Request-URI标识的任何信息(以实体的形式)。”
简单地说,
GET
方法是为了只使用URI来获取某个资源而创建的,更简单地说,如果你只使用URI就可以获取某个资源,那么GET
就是你应该使用的方法。事实上,您可以使用
GET
请求发送body,但它将被忽略(更多信息请访问:(第10页)如果出于任何原因需要传递主体,则需要使用不同的方法。
POST
是一个突出的示例:“POST方法用于请求源服务器接受包含在请求中的实体,作为由请求行中的请求URI标识的资源的新从属。”
如果您正在使用REST API,我强烈建议您阅读HTTP规范https://www.rfc-editor.org/rfc/rfc2616
gfttwv5a2#
请求带正文的数据不好吗?
是的,很糟糕。
问题是,在HTTP中,GET方法被明确定义为不包含请求主体。
GET请求消息中的有效负载没有定义的语义;在GET请求中发送有效载荷正文可能会导致一些现有的实现拒绝请求。-- RFC 7231
这里的主要问题是,早期版本的HTTP规范在处理请求中的消息体时存在一些不明确的地方,实际上,将消息体放入GET请求是“未定义的行为”。
工作组强烈希望确保该标准保持向后兼容。
REST的部分 * 要点 * 是我们都使用一个公共标准,因此通用工具(浏览器、缓存、反向代理、蜘蛛...)适用于 * 每个人 * --或者更具体地说,适用于遵守该标准的每个人。
对于
GET
,当您考虑缓存语义时,包含消息正文是没有意义的。HTTP中的缓存语义目前由RFC 7134定义,高级总结是target-uri是主缓存键;缓存只需要理解HTTP请求中的元数据就可以正确地完成它们的工作。如果我们要将语义应用于GET请求的主体,我们还需要以一种通用的方式定义这些语义如何影响缓存行为。
例如,如果您设想一个查询场景(如GraphQL),响应中的预期表示取决于编码到请求主体中的信息。因此,现在您需要开始定义何时两个请求主体“相同”--白色是否重要?内容编码是否重要?如果主体被压缩会怎样?等等......
对于不安全的请求(例如POST),我们不会遇到这样的问题,因为符合标准的缓存“必须”(MUST)写入不安全的请求。没有必要探究请求的消息体的表示,因为不存在内容会改变这一需求的情况。
已经有人尝试为HTTP方法创建一个新的标准,这个标准是安全的 * 并且 * 包括一个消息体。在某种意义上,我们引入了一个新的方法令牌,并声明语义是安全的(以便我们可以执行抢先获取,并在不可靠的网络上重复请求),并且也许公共高速缓存不能存储响应,而是必须将每个请求转发给源服务器。
也就是说,人们已经意识到差距有一段时间了,而且这个问题还没有一个标准化的解决方案--所以可能有一些困难的方面并不明显(除了采用与惰性的政治问题)。