我正在使用两个不同的 API,都使用
GET
请求,但处理请求数据的方式不同:
API 1 要求在请求正文中发送数据,即使 HTTP 方法是
GET
。$config = [
'method' => 'GET',
'url' => 'http://example.com/api/endpoint',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => [
'key1' => 'value1',
'key2' => 'value2',
],
];
API 2 要求将数据作为 URL 中的查询参数发送。
示例:
$config = [
'method' => 'GET',
'url' => 'http://example.com/api/endpoint',
'headers' => [
'Content-Type' => 'application/json',
],
'query' => [
'key1' => 'value1',
'key2' => 'value2',
],
];
这两个 API 都使用
GET
方法,但它们对传递数据的要求不同。这使得决定何时使用查询参数以及何时对 GET
请求使用请求正文变得具有挑战性。
问题:
query
请求是使用查询参数 (body
) 还是请求正文 (GET
)?GET
请求接受正文中的数据是否常见或正确?任何指导、最佳实践或示例,我们将不胜感激!
$options = ['headers' => $request['headers']];
if ($request['method'] === 'GET') {
if ($request['isRequestRawBody']) {
$options['body'] = json_encode($request['body']);
} else {
$options['query'] = $request['body'];
}
} else {
$contentType = $request['headers']['Content-Type'] ?? '';
switch ($contentType) {
case 'application/x-www-form-urlencoded':
$options['form_params'] = $request['body'];
break;
case 'application/json':
$options['json'] = $request['body'];
break;
case 'multipart/form-data':
$options['multipart'] = array_map(function ($key, $value) {
return ['name' => $key, 'contents' => $value];
}, array_keys($request['body']), $request['body']);
break;
default:
$options['body'] = $request['body'];
}
}
return $options;
GET 请求永远不应该有请求正文。 HTTP协议规范不允许这样做。您的
body
属性的内容可能会以某种方式转换为查询参数(或完全忽略)。
技术上可以通过 GET 请求提交正文,但这并未得到 HTTP/1.1 或 HTTP/2 标准的广泛支持或要求。
如果需要正文,请使用 POST、PUT 或 PATCH 方法。我见过的每个接受 JSON 输入的 API 都使用不同的方法。您可以对 JSON 进行 URL 编码,但会受到 URL 长度的限制。
GET 旨在检索数据,通常不需要在请求中提交大量信息。
如果您正在实现客户端,则可以安全地忽略 GET 请求中的正文。
RFC9112 指出:
客户端不应该在 GET 请求中生成内容,除非该请求是直接向源服务器发出的,并且该源服务器先前已在带内或带外表明此类请求具有目的并且将得到充分支持。源服务器不应该依赖私有协议来接收内容,因为 HTTP 通信的参与者通常不知道请求链上的中介。