首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >口香糖未正确发送PSR-7柱身

口香糖未正确发送PSR-7柱身
EN

Stack Overflow用户
提问于 2016-01-03 13:57:15
回答 2查看 18.6K关注 0票数 9

它要么没有被发送,要么没有被正确地接收。直接从命令行使用curl (使用-d选项)或使用PHP (使用CURLOPT_POSTFIELDS)确实有效。

我从PSR-7请求开始:

代码语言:javascript
复制
$request = GuzzleHttp\Psr7\Request('POST', $url);

我添加了身份验证头,它根据API正确地进行身份验证:

代码语言:javascript
复制
$request = $request->withHeader('Authorization', 'Bearer ' . $accessToken);

然后我添加请求体:

代码语言:javascript
复制
// The parameter for the API function
$body = \GuzzleHttp\Psr7\stream_for('args=dot');
$request = $request->withBody($body);

我可以将消息发送到API:

代码语言:javascript
复制
$client = new \GuzzleHttp\Client();
$response = $client->send($request, ['timeout' => 2]);

我得到的响应表明,API根本没有看到"args“参数。我尝试将身份验证令牌移动到args:

代码语言:javascript
复制
'args=dot&access_token=123456789'

这应该可以使用命令行(-d access_token=123456789)中的curl,但是API在发送curl (6.x)时也没有看到这个参数。

我可以看到消息中确实包含了主体:

代码语言:javascript
复制
var_dump((string)$request->getBody());
// string(8) "args=dot"
// The "=" is NOT URL-encoded in any way.

那么这里会出什么问题呢?参数是未发送,还是以错误的格式发送(可能“=”正在编码?),还是使用了错误的内容类型?由于HTTP消息是格式化的,并且发送到了很多层深处,所以很难看到在使用Guzzle时正在“连线上”发送什么。

编辑:调用一个本地测试脚本而不是远程API,我得到了以下原始消息细节:

代码语言:javascript
复制
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提供了请求中的两个额外的头字段:

代码语言:javascript
复制
CONTENT-TYPE: application/x-www-form-urlencoded
ACCEPT: */*

我将猜测是内容类型的标题,这是缺少的口吻请求,这是问题的根源。这是口香糖虫吗?它不应该总是发送一个内容类型,基于它所做的假设,即列于文件中

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-08 21:24:59

GuzzleHttp\Client提供所有必要的包装。

代码语言:javascript
复制
$response = $client->post(
    $uri,
    [
        'auth' => [null, 'Bearer ' . $token],
        'form_params' => $parameters,
]);

可用的文档口吻请求选项

编辑:但是,如果在GuzzleHttp\Pool中使用了您的请求,那么您可以简单地将所有内容归纳为以下内容:

代码语言:javascript
复制
$request = new GuzzleHttp\Psr7\Request(
    'POST',
    $uri,
    [
       'Authorization' => 'Bearer ' . $token,
       'Content-Type' => 'application/x-www-form-urlencoded'

    ],
    http_build_query($form_params, null, '&')
);
票数 15
EN

Stack Overflow用户

发布于 2016-01-03 15:08:46

Content-Type头是问题所在。通常情况下,口香糖会握着你的手,插入它认为必要的标题,并根据你给它的内容和你给它的方式对Content-Type做一个很好的猜测。

有了口香糖的PSR-7信息,所有的手握都做不到。它严格地将所有标题留给您处理。因此,当向PSR-7 Request添加POST参数时,必须显式设置Content:

代码语言:javascript
复制
$params = ['Foo' => 'Bar'];
$body = \GuzzleHttp\Psr7\stream_for(http_build_query($params));
$request = $request->withBody($body);
$request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');

以数组的形式传递幻灯并让口香糖来处理其余部分的能力,不适用于Guzzle的PSR-7实现。这有点笨拙,因为您需要将POST参数序列化为HTTP查询字符串,然后将其放入流中,但您已经有了。可能有一种更简单的方法来处理这个问题(例如,一个我不知道的包装类),在接受这个答案之前,我会等着看是否有其他的。

还要注意,如果构造multipart/form-data请求消息,则需要将边界字符串添加到Content:

代码语言:javascript
复制
$request = $request->withHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);

其中,$boundary可以类似于uniq(),并用于构造多个部分的主体。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34577278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档