当前位置:  开发笔记 > 编程语言 > 正文

Guzzle没有正确发送PSR-7 POST机身

如何解决《Guzzle没有正确发送PSR-7POST机身》经验,为你挑选了2个好方法。

它未被发送或未被正确接收.使用curl命令行直接(使用-d选项)或PHP(使用CURLOPT_POSTFIELDS)做的工作.

我从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消息被格式化并发送了很多层.

编辑:调用本地测试脚本而不是远程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 bug吗?它是否应该根据文档中列出的假设发送内容类型?



1> Jason..:

Content-Type标题是问题.通常情况下,Guzzle会握住你的手并插入它认为必要的标题,并Content-Type根据你给出的内容,以及你如何给出它来做出很好的猜测.

使用Guzzle的PSR-7消息,没有完成任何手持操作.它严格保留所有标题供您处理.因此,在将POST参数添加到PSR-7时Request,必须显式设置Content-Type:

$params = ['Foo' => 'Bar'];
$body = new \GuzzleHttp\Psr7\stream_for(http_build_query($params));
$request = $request->withBody($body);
$request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');

能够将params作为一个数组传递并让Guzzle完成剩下的工作,并不适用于Guzzle的PSR-7实现.它有点笨拙,因为你需要将POST参数序列化为HTTP查询字符串,然后将其粘贴到流中,但是你有它.可能有一种更简单的方法来处理这个问题(例如我不知道的包装类),在接受这个答案之前我会等待,看看是否有任何问题.

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

$request = $request->withHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);

哪里$boundary可以是类似的东西uniq(),用于建造多部分身体.



2> Shaun Bramle..:

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

$response = $client->post(
    $uri,
    [
        'auth' => [null, 'Bearer ' . $token],
        'form_params' => $parameters,
]);

可用文档Guzzle请求选项

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

$request = new GuzzleHttp\Psr7\Request(
    'POST',
    $uri,
    [
       'Authorization' => 'Bearer ' . $token,
       'Content-Type' => 'application/x-www-form-urlencoded'

    ],
    http_build_query($form_params, null, '&')
);

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有