[英]Using Paypal REST api and PHP cURL to post invoice (draft) constantly returns 415 Unsupported Media Type
[英]PHP cURL POST returns a 415 - Unsupported Media Type
我有一個簡單的 PHP 腳本,它通過 cURL 發送一個 HTTP POST 請求,並期望一個 json 字符串作為響應(本來希望使用像 pecl_http/HTTPRequest 這樣的現有庫,但不能)。 呼叫始終失敗並顯示 415 錯誤 - 不支持的媒體類型。 我想我沒有正確配置 cURL,但經過多次搜索,我無法找出我做錯了什么。 這是一些代碼:
class URLRequest
{
public $url;
public $headers;
public $params;
public $body;
public $expectedFormat;
public $method;
public function URLRequest($aUrl, array $aHeaders, array $aParams, $aFormat = "json", $isPost = false, $aBody = "+")
{
$this->url = $aUrl;
$this->headers = $aHeaders;
$this->params = $aParams;
$this->expectedFormat = $aFormat;
$this->method = ($isPost ? "POST" : "GET");
$this->body = $aBody;
}
public function exec()
{
$queryStr = "?";
foreach($this->params as $key=>$val)
$queryStr .= $key . "=" . $val . "&";
//trim the last '&'
$queryStr = rtrim($queryStr, "&");
$url = $this->url . $queryStr;
$request = curl_init();
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_HEADER, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $this->headers);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
if($this->method == "POST")
{
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $this->body);
//this prevents an additions code 100 from getting returned
//found it in some forum - seems kind of hacky
curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:"));
}
$response = curl_exec($request);
curl_close($request);
preg_match("%(?<=HTTP/[0-9]\.[0-9] )[0-9]+%", $response, $code);
$resp = "";
if($this->expectedFormat == "json")
{
//parse response
}
elseif($this->expectedFormat == "xml")
{
//parse response
}
return $resp;
}
}
$url = "http://mydomain.com/myrestcall";
$query = array( "arg_1" => "test001",
"arg_2" => "test002",
"arg_3" => "test003");
$headers = array( "Accept-Encoding" => "gzip",
"Content-Type" => "application/json",
"Accept" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");
$body = array( "body_arg_1" => "test021",
"body_arg_2" => array("test022", "test023"),
"body_arg_3" => "test024");
$request = new URLRequest($url, $headers, $query, "json", true, $body);
$response = $request->exec();
...和回應:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Content-Type: text/html;charset=utf-8
Content-Length: 1047
Date: Mon, 18 Jun 2012 16:30:44 GMT
<html><head><title>JBoss Web/2.1.3.GA - Error report</title></head><body><h1>HTTP Status 415 - </h1><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().</u></p><h3>JBoss Web/2.1.3.GA</h3></body></html>
任何見解或想法?
提前致謝!
問題解決了! 這是問題:
發送標頭的關聯數組不適用於 cURL。 有幾個論壇散布在展示使用關聯數組作為標題的示例。 不要這樣做!
正確的方法(也散布在互聯網上,但我太密集以至於沒有注意到)是將標題鍵/值對構造為字符串,並在設置 CURLOPT_HTTPHEADER 選項時傳遞這些字符串的標准數組。
所以總結一下,
錯誤的:
$headers = array( "Accept-Encoding" => "gzip",
"Content-Type" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");
對:
$headers = array( "Accept-Encoding: gzip",
"Content-Type: application/json",
"custom_header_1: test011",
"custom_header_2: test012",
"custom_header_3: test013");
我希望這對未來的其他一些高尚的傻瓜有用,以免他們像我一樣浪費大量時間進行調試。
如果我不得不猜測,我會假設相同的規則也適用於 POST 正文鍵/值對,這就是為什么 @drew010 關於使用http_build_query()
或json_encode()
對您的消息正文進行字符串化的評論很棒想法也是如此。
感謝大家的非常有用的意見,以及您的時間和考慮。 最后,對 http 流量(通過 Wireshark 捕獲)的並排比較揭示了這個問題。
謝謝!
我認為問題在於您將數組作為CURLOPT_POSTFIELDS
選項CURLOPT_POSTFIELDS
。 通過傳遞一個數組,當服務器可能需要application/x-www-form-urlencoded
時,這會強制POST
請求使用multipart/form-data
。
嘗試改變
curl_setopt($request, CURLOPT_POSTFIELDS, $this->body);
到
curl_setopt($request, CURLOPT_POSTFIELDS, http_build_query($this->body));
有關更多信息以及此答案,請參閱http_build_query : 我的 cURL 請求混淆了某些服務器?
我遇到了同樣的問題,我修復了更改標題。
我的代碼:
$authorization = 'authorization: Bearer '.trim($apiKey);
$header = [
'Content-Type: application/json',
$authorization
];
curl_setopt($session, CURLOPT_HTTPHEADER, $header);
我不知道為什么數組函數不起作用:
curl_setopt($session, CURLOPT_HTTPHEADER, array('Content-Type:
application/json',
$authorization));
這對我有用
$data ="data";
$headers = [
"Content-Type: application/json",
"X-Content-Type-Options:nosniff",
"Accept:application/json",
"Cache-Control:no-cache"
];
$auth = $USER . ":" . $PASSWORD;
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL, $url);
curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl,CURLOPT_ENCODING, "");
curl_setopt($curl,CURLOPT_MAXREDIRS, 10);
curl_setopt($curl,CURLOPT_TIMEOUT, 0);
curl_setopt($curl,CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($curl,CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_USERPWD, $auth);
curl_setopt($curl,CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.