Intereting Posts
Проверка Javascript и проверка PHP? Соединение с WebSocket с «ws: //mydomain.com: 8084 /? Peer_id = 123» не выполнено: ошибка при установлении соединения: net :: ERR_CONNECTION_TIMED_OUT Как показать значение переключателя с помощью PHP Отдельная версия веб-сайта Как обновить значения в моей БД новыми значениями из тегов <select> и <input>? mysql | Запрос из пустой колонки и FIND_IN_SET перенаправить загрузку php-заголовка PHP SLIM не принимает точку (.) В аргументе uri PHP + S3: разрешение отклонено при удалении файла с помощью unlink () Используя PHP, как я могу проверить строку для шаблона, а затем изменить ее? Скрыть заголовки подкатегорий на странице с одной родительской подкатегорией WooCommerce Измените версию PHP на сервере, используя либо .htaccess, либо php.ini Извлеките все теги text и img из HTML в PHP. Как реализовать этот сценарий с помощью PHP? Как использовать пространства имен PHP с автозагрузкой?

PHP cURL POST возвращает 415 – Неподдерживаемый тип носителя

У меня есть простой PHP-скрипт, который отправляет HTTP-запрос POST через cURL и ожидает ответную строку 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 . Передавая массив, это заставляет запрос POST использовать multipart/form-data когда сервер, вероятно, ожидает application/x-www-form-urlencoded .

Попробуйте изменить

 curl_setopt($request, CURLOPT_POSTFIELDS, $this->body); 

в

 curl_setopt($request, CURLOPT_POSTFIELDS, http_build_query($this->body)); 

См. Http_build_query для получения дополнительной информации, а также этого ответа: Мой запрос cURL смущает некоторые серверы?