9

送信されていないか、正しく受信されていません。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]);

返された応答は、「args」パラメーターが API によって認識されなかったことを示しています。認証トークンを引数に移動しようとしました:

'args=dot&access_token=123456789'

これは機能するはずでありコマンド ラインから curl を-d access_token=123456789使用しても機能します ( ) が、API は上記のように cia curl (6.x) を送信するときにもそのパラメーターを認識できません。

メッセージに本文が含まれていることがわかります。

var_dump((string)$request->getBody());
// string(8) "args=dot"
// The "=" is NOT URL-encoded in any way.

では、ここで何がうまくいかないのでしょうか?パラメータが送信されていないか、間違った形式で送信されているか ('=' がエンコードされている可能性がありますか?)、または間違ったコンテンツ タイプが使用されている可能性がありますか? HTTP メッセージはフォーマットされており、何層にもわたって送信されているため、Guzzle を使用しているときに「ネットワーク上」で送信されているものを確認することは困難です。

編集:リモート 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は、リクエストに2つの追加ヘッダーフィールドを提供します:

CONTENT-TYPE: application/x-www-form-urlencoded
ACCEPT: */*

問題の原因は、Guzzle リクエストにない content-type ヘッダーだと思います。これはGuzzleのバグですか?ドキュメントに記載されている仮定に基づいて、常に Content-Type を送信する必要はありませんか?

4

2 に答える 2

15

Content-Typeヘッダーが問題でした。通常、Guzzle はあなたの手を握り、必要と思われるヘッダーを挿入し、あなたが与えたものと与えた方法Content-Typeに基づいて適切な推測を行います。

Guzzle の PSR-7 メッセージを使用すると、そのような手間は一切かかりません。処理するすべてのヘッダーを厳密に残します。したがって、 POST パラメータを PSR-7 に追加するときRequestは、 Content-Type を明示的に設定する必要があります:

$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');

params を配列として渡し、Guzzle に残りを処理させる機能は、Guzzle の PSR-7 実装には適用されません。POST パラメーターを HTTP クエリ文字列にシリアル化し、それをストリームに貼り付ける必要があるため、少し不器用ですが、これで完了です。これを処理するもっと簡単な方法があるかもしれません (たとえば、私が認識していないラッパー クラス)。

multipart/form-dataRequest メッセージを作成する場合は、Content-Type に境界文字列を追加する必要があることにも注意してください。

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

マルチパートボディの構築に使用さ$boundaryれるようなものがあります。uniq()

于 2016-01-03T15:08:46.837 に答える