【发布时间】:2020-05-23 17:49:20
【问题描述】:
它要么没有被发送,要么没有被正确接收。直接从命令行(使用 -d 选项)或从 PHP(使用 CURLOPT_POSTFIELDS)使用 curl 确实有效。
我从 PSR-7 请求开始:
$request = GuzzleHttp\Psr7\Request('POST', $url);
我添加了身份验证标头,它正确地针对 API 进行身份验证:
$request = $request->withHeader('Authorization', 'Bearer ' . $accessToken);
然后我添加请求正文:
// The parameter for the API function
$body = \GuzzleHttp\Psr7\stream_for('args=dot');
$request = $request->withBody($body);
我可以将消息发送到 API:
$client = new \GuzzleHttp\Client();
$response = $client->send($request, ['timeout' => 2]);
我得到的响应表明 API 根本没有看到“args”参数。我已经尝试将身份验证令牌移动到 args:
'args=dot&access_token=123456789'
这应该可以工作,确实可以从命令行 (-d access_token=123456789) 使用 curl,但是在发送 cia curl (6.x) 时,API 也无法看到该参数。
我可以看到消息确实包含正文:
var_dump((string)$request->getBody());
// string(8) "args=dot"
// The "=" is NOT URL-encoded in any way.
那么这里可能出了什么问题?是参数没有被发送,还是以错误的格式发送(可能'='正在被编码?),或者可能是使用了错误的内容类型?使用 Guzzle 时很难看到“在线”发送的内容,因为 HTTP 消息经过格式化并发送了很多层。
编辑:调用 local test script 而不是远程 API,我得到了这个原始消息详细信息:
POST
CONNECTION: close
CONTENT-LENGTH: 62
HOST: acadweb.co.uk
USER-AGENT: GuzzleHttp/6.1.1 curl/7.19.7 PHP/5.5.9
args=dot&access_token=5e09d638965288937dfa0ca36366c9f8a44d4f3e
所以看起来主体 正在 被发送,所以我猜缺少其他东西来告诉远程 API 如何解释该主体。
编辑:有效的命令行 curl 发送到同一个测试脚本,在请求中为我提供了两个额外的标头字段:
CONTENT-TYPE: application/x-www-form-urlencoded
ACCEPT: */*
我猜这是 Guzzle 请求中缺少的内容类型标头,这是问题的根源。那么这是一个 Guzzle 错误吗?它不应该总是发送一个 Content-Type,基于它所做的假设是 listed in the documentation 吗?
【问题讨论】: