![](/img/trans.png)
[英]Guzzle POST request results in 500 error even though Curl for that works
[英]cURL POST request works, Guzzle 6 does not
語境:
一段時間以來,我一直在研究如何使這項工作發揮作用,但我根本不明白為什么 Guzzle 不能滿足這個特定的要求。 相同的初始化和請求結構適用於我的一些基本單元測試,但是當涉及到 API 到 API 通信時,Guzzle 只是不合作。
問題:
我的意思是,它不包括我在$headers
數組中設置的$headers
,並且請求正文為空。
想要的結果:
為了確認這是 Guzzle 的問題,我已經用典型的 cURL 語法寫出了請求,並且請求順利通過。 我只需要一些關於如何使用 Guzzle 進行這項工作的指導,因為我喜歡 Guzzle 提供的抽象而不是冗長的 cURL 請求。
工作 cURL 請求:
$headers = array(
'Authorization: Bearer '.$sharedSecret,
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json',
'Content-Length: '.strlen($loginDetails),
);
$curlOptions = array(
CURLOPT_URL => API_URL.'member/SessionManager',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => FALSE,
CURLOPT_HEADER => FALSE,
CURLOPT_FOLLOWLOCATION => FALSE,
CURLOPT_ENCODING => "",
CURLOPT_USERAGENT => "PORTAL",
CURLOPT_AUTOREFERER => TRUE,
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $loginDetails,
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_VERBOSE => FALSE
);
try {
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$response = curl_getinfo($ch);
curl_close($ch);
if ($content === FALSE) {
throw new Exception(curl_error($ch), curl_errno($ch));
} else {
return true;
}
} catch(Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
Guzzle 客戶端在一個全局文件中初始化,該文件創建了一個容器,用於存儲我們在整個應用程序中使用的各種對象。 我將它包括在內,以防我錯過了 Guzzle 文檔中沒有的重要內容。
Guzzle 初始化:
$container['client'] = function ($c) {
return new \GuzzleHttp\Client([
'base_uri' => API_URL,
'timeout' => 30.0,
'allow_redirects' => true,
'verify' => false,
'verbose' => true,
[
'headers' => [
'Authorization' => 'Bearer '.$sharedSecret,
]
],
]);
};
非工作 Guzzle 請求:
$headers = array(
'Authorization' => 'Bearer '.$sharedSecret,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
'Content-Length'=> strlen($loginDetails),
);
try {
$response = $this->client->post('/api/member/SessionManager',
['debug' => true],
['headers' => $headers],
['body' => $loginDetails]
);
if($response) {
$this->handleResponse($response);
}
} catch (GuzzleHttp\Exception\ClientException $e) {
$response->getResponse();
$responseBodyAsString = $response->getBody()->getContents();
}
是否刪除 Guzzle 初始化中的headers
數組,都沒有關系。 在請求中找不到授權標頭(通過 tcpdump、Wireshark 和接收 API 錯誤日志確認),並且 Guzzle 的調試輸出沒有顯示我的標頭,也沒有我的請求正文在請求中的任何位置。
我很難理解為什么這不起作用,並且非常想了解。 我可以走不使用 Guzzle 的路線,但由於簡潔,我真的更願意。 任何投入將不勝感激。
在cURL請求中,被調用的 API URL 是
API_URL.'member/SessionManager'
而在Guzzle請求中,被調用的 API URL 有額外的文本“/api/”(假設 API_URL 在兩種情況下定義相同)
new \\GuzzleHttp\\Client([ 'base_uri' => API_URL,
...
$this->client->post('/api/member/SessionManager',
感謝這個問題很老,但我想我會分享我的經驗,因為我也為此苦苦掙扎。 相當於:
CURLOPT_POSTFIELDS => $loginDetails,
在 Guzzle 是:
"query" => $loginDetails
另外,我發現如果base_uri
不以/
結尾,Guzzle 會誤解它。
考慮到所有這些,您的 POST 請求應如下所示:
$response = $this->client->post('api/member/SessionManager', // Removed the first / as it's part of the base_uri now
['debug' => true],
['headers' => $headers],
['query' => $loginDetails] // Replaced "body" with "query"
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.