Я могу запросить URL-адрес веб-службы «WS» непосредственно из браузера, но когда я использую методы file_get_contents () или fopen в своем коде, я получаю сообщение об ошибке. Есть ли у кого-то решение без использования завитка?
public function sendHttpRequest($data) { ini_set('user_agent', 'PHP'); $context_options = array( 'http' => array( 'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", 'content' => json_encode($data) ) ); $context = stream_context_create($context_options); //line error "line 196" $result = file_get_contents($this->WS, false, $context); }
Сообщение об ошибке:
не удалось открыть поток: HTTP-запрос не удался! HTTP / 1.1 400 Bad Request в /mnt/hgfs/case/src/bat/abc/send-entry.php в строке 196
НОЛЬ
я изменил параметры контекста на это, но все еще получаю HTTP/1.1 400 Bad Request
$context_options = array( 'http' => array( 'method' => 'POST', 'header' => "Date: " . gmdate("D, d MYH:i:s T", time()) . "\r\n" . get_headers($this->WS)[2] . "\r\n" . " x-powered-by: PHP/" . phpversion() . "\r\n" . " " . get_headers($this->WS)[5] . "\r\n" . " Pragma: no-cache" . "\r\n" . " Content-Length: " . strlen($this->content) . "\r\n" . " Content-Type: text/xml" . "\r\n" . " " .get_headers($this->WS)[9] . "\r\n" . " Connection: close", 'content' => $this->content ) var_dump(get_headers($this->WS))
данные отправляются на сервер с адресом http://192.168.xxx.xxx/WS
здесь var_dump массива для отправки
array(16) { ["method"]=> string(24) "WS" ["LOGIN"]=> string(12) "xxx" ["DATE1"]=> string(10) "1970-01-01" ["DATE2"]=> string(0) "" ["TRANSMISSION"]=> INT(8) ["REF"]=> int(206) ["FORMAT"]=> int(7) ["DOMAIN"]=> int(3) ["TYPE1"]=> int(15) ["TYPE2"]=> NULL ["NAME"]=> string(12) "JDOE" ["ADRESSE"]=> string(0) "" ["ADRESSE2"]=> string(0) "" ["ADRESSE3"]=> string(0) "" ["ADRESSE4"]=> string(0) "" ["REF2"]=> string(0) "" }
вот полная ошибка сообщения
Предупреждение: file_get_contents ( http://192.168.xxx.xxx/WS ): не удалось открыть поток: запрос HTTP не удался! HTTP / 1.1 400 Bad Request в /mnt/hgfs/case/src/bat/abc/send-entry.php в строке 182
рабочий код:
$context_options1 = array( 'http' => array( 'method' => 'POST', 'header' => "Date: " . gmdate("D, d MYH:i:s T", time()) . "Accept: application/xml" . "Content-Type: application/xml" . "Content-Length: " . strlen($this->content), 'content' => $this->content ) );
Для запроса POST
требуется заголовок Content-Length
:
$content = json_encode($data); $context_options = array( 'http' => array( 'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($content) . "\r\n", 'content' => $content ) );
Это, очевидно, сделано с помощью обертки автоматически, так что есть что-то еще. Возможно, опустите последнюю строку («\ r \ n») в заголовках.
Сначала эмулируйте браузер. Проверьте, что инструменты разработчика, которые его заголовки отправляют, точно соответствуют Сервису. И подражать ему. Это поможет найти, где вы ошибаетесь.
Например, службе может понадобиться «Тип контента: multipart / form-data» вместо типа Application / x-form. Может потребоваться Content-encoding или что-то еще, что нужно предоставить.
У меня есть подозрение, что это связано с несоответствием между объявленным медиатипом и фактической полезной нагрузкой. Правильный код состояния для этого будет 415: Unprocessable Entity , но может появиться и 400.
Чтобы взять свой первый пример: вы объявляете urlencoded данные из html-формы, за которой следует JSON. Я думаю, что здесь правильный код:
public function sendHttpRequest($data) { $data = json_encode($data) $context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => array( 'Content-Type: application/json', 'Content-Length: ' . strlen($data), 'Connection: close', ), 'content' => $data, ), )); $result = file_get_contents($this->WS, false, $context); }
Вы также, кажется, помещаете много заголовков в свой запрос, которые просто не принадлежат им, такие как Pragma
и другие заголовки управления кешем. Они действительно должны быть отправлены сервером, а не клиентом.
Кроме того, за этот ответ убедитесь, что все эти $this->WS
содержатся в закодированном виде.