HTTP GET with request body
HTTP GET with request body
技术背景
在HTTP协议中,GET请求通常用于从服务器获取资源,传统认知里GET请求不应该包含请求体。但HTTP规范并未明确禁止GET请求携带请求体,这就引发了关于能否以及是否应该在GET请求中使用请求体的讨论。
实现步骤
发送GET请求并携带请求体
在理论上,只要按照HTTP协议格式构建请求,就可以在GET请求中携带请求体。例如使用netcat
工具发送请求:
1 |
|
上述示例中,在GET请求里添加了长度为6的请求体。
核心代码
不同工具对GET请求携带请求体的支持
使用curl
发送GET请求并携带请求体
1 |
|
不同客户端对GET请求携带请求体的处理
在XMLHttpRequest
中,根据标准,请求方法为GET
或HEAD
时,send()
方法会忽略请求体:
1 |
|
最佳实践
避免使用GET请求携带请求体
从兼容性和规范性角度考虑,应尽量避免在GET请求中使用请求体。可以采用以下替代方案:
- 使用查询字符串:将参数添加到URL的查询字符串中,例如
example.com/category/{catid}/item/{itemid}?sortby=itemname&order=asc
。 - 使用路径重写:通过
mod_rewrite
等技术,将参数包含在URL路径中,如example.com/category/{catid}/item/{itemid}/{sortby}/{order}
。 - 使用HTTP头部:将参数放在HTTP头部中。
- 使用POST请求:如果需要发送请求体,优先考虑使用POST请求。
特殊情况处理
如果确实需要支持类似GET请求携带请求体的功能,可以支持POST请求并添加X-HTTP-Method-Override: GET
头部,让服务器将该POST请求视为GET请求处理。
常见问题
兼容性问题
许多服务器、代理和客户端可能不支持或会拒绝处理带有请求体的GET请求。例如,Google、Bing、Apple等网站会将带有请求体的GET请求视为错误请求,返回400 Bad Request
;AWS CloudFront会对包含请求体的GET请求返回403 Forbidden
。
缓存问题
使用带有请求体的GET请求会影响缓存机制。代理服务器通常根据请求的URL和头部信息来缓存响应,不会考虑请求体的内容,这可能导致缓存无法正常工作。
标准规范问题
虽然HTTP规范没有明确禁止GET请求携带请求体,但GET请求的语义表明,服务器仅根据请求的URL来确定要检索的资源,请求体不应该影响请求的结果。因此,在GET请求中使用请求体违反了HTTP协议的设计初衷。
HTTP GET with request body
https://119291.xyz/posts/http-get-with-request-body/