PHP – `get_headers` возвращает« 400 Bad Request »и« 403 Forbidden »для действительных URL-адресов?

Рабочее решение внизу описания!

Я запускаю PHP 5.4 и пытаюсь получить заголовки списка URL-адресов.

По большей части все работает нормально, но есть три URL-адреса, которые вызывают проблемы (и, вероятно, больше, при более широком тестировании).

'http://www.alealimay.com' 'http://www.thelovelist.net' 'http://www.bleedingcool.com' 

Все три сайта отлично работают в браузере и производят следующие ответы заголовков:

(Из Сафари)

успешные заголовки

Обратите внимание, что все три ответа заголовка: Code = 200

Но получение заголовков через PHP, используя get_headers

 stream_context_set_default(array('http' => array('method' => "HEAD"))); $headers = get_headers($url, 1); stream_context_set_default(array('http' => array('method' => "GET"))); 

… возвращает следующее:

 url ...... "http://www.alealimay.com" headers | 0 ............................ "HTTP/1.0 400 Bad Request" | content-length ............... "378" | X-Synthetic .................. "true" | expires ...................... "Thu, 01 Jan 1970 00:00:00 UTC" | pragma ....................... "no-cache" | cache-control ................ "no-cache, must-revalidate" | content-type ................. "text/html; charset=UTF-8" | connection ................... "close" | date ......................... "Wed, 24 Aug 2016 01:26:21 UTC" | X-ContextId .................. "QIFB0I8V/xsTFMREg" | X-Via ........................ "1.0 echo109" url ...... "http://www.thelovelist.net" headers | 0 ............................ "HTTP/1.0 400 Bad Request" | content-length ............... "378" | X-Synthetic .................. "true" | expires ...................... "Thu, 01 Jan 1970 00:00:00 UTC" | pragma ....................... "no-cache" | cache-control ................ "no-cache, must-revalidate" | content-type ................. "text/html; charset=UTF-8" | connection ................... "close" | date ......................... "Wed, 24 Aug 2016 01:26:22 UTC" | X-ContextId .................. "aNKvf2RB/bIMjWyjW" | X-Via ........................ "1.0 echo103" url ...... "http://www.bleedingcool.com" headers | 0 ............................ "HTTP/1.1 403 Forbidden" | Server ....................... "Sucuri/Cloudproxy" | Date ......................... "Wed, 24 Aug 2016 01:26:22 GMT" | Content-Type ................. "text/html" | Content-Length ............... "5311" | Connection ................... "close" | Vary ......................... "Accept-Encoding" | ETag ......................... "\"57b7f28e-14bf\"" | X-XSS-Protection ............. "1; mode=block" | X-Frame-Options .............. "SAMEORIGIN" | X-Content-Type-Options ....... "nosniff" | X-Sucuri-ID .................. "11005" 

Это происходит независимо от изменения stream_context

 //stream_context_set_default(array('http' => array('method' => "HEAD"))); $headers = get_headers($url, 1); //stream_context_set_default(array('http' => array('method' => "GET"))); 

Производит тот же результат.

Никаких предупреждений или ошибок для любого из них (как правило, ошибки подавляются с помощью @get_headers , но нет никакой разницы в любом случае).

Я проверил свой php.ini и установил allow_url_fopen в On .

Я направляюсь к stream_get_meta_data и не интересуюсь решениями CURL . stream_get_meta_data (и его сопровождающий fopen ) провалится в том же месте, что и get_headers , поэтому исправление будет исправлено и в этом случае.

Обычно, если есть перенаправления, вывод выглядит следующим образом:

 url ...... "http://www.startingURL.com/" headers | 0 ............................ "HTTP/1.1 301 Moved Permanently" | 1 ............................ "HTTP/1.1 200 OK" | Date | | "Wed, 24 Aug 2016 02:02:29 GMT" | | "Wed, 24 Aug 2016 02:02:32 GMT" | | Server | | "Apache" | | "Apache" | | Location ..................... "http://finishingURL.com/" | Connection | | "close" | | "close" | | Content-Type | | "text/html; charset=UTF-8" | | "text/html; charset=UTF-8" | | Link ......................... "; rel=\"https://api.w.org/\", ; rel=shortlink" 

Почему сайты работают в браузерах, но сбой при использовании get_headers ?

Существуют разные сообщения SO, обсуждающие одно и то же, но решение для всех из них не относится к этому случаю:

POST требует Content-Length (я отправляю запрос HEAD , содержимое не возвращается)

URL содержит данные UTF-8 (единственные символы в этих URL-адресах – от латинского алфавита)

Невозможно отправить URL-адрес с пробелами в нем (эти URL-адреса не содержат пробелов и очень обычны во всех отношениях)

Решение!

(Спасибо Макс в ответах ниже, чтобы указать мне на правильный путь.)

Проблема заключается в том, что не существует заранее определенного user_agent , без установки в php.ini или объявления его в коде.

Итак, я меняю user_agent чтобы имитировать браузер, сделать это, а затем вернуть его обратно к указанию значения (скорее всего, пустое).

 $OriginalUserAgent = ini_get('user_agent'); ini_set('user_agent', 'Mozilla/5.0'); $headers = @get_headers($url, 1); ini_set('user_agent', $OriginalUserAgent); 

Здесь найдено изменение агента пользователя.

Solutions Collecting From Web of "PHP – `get_headers` возвращает« 400 Bad Request »и« 403 Forbidden »для действительных URL-адресов?"

Это происходит потому, что все три этих сайта проверяют заголовок UserAgent запроса и ответа с ошибкой в ​​этом случае, если он не может быть сопоставлен. Функция get_headers не отправляет этот заголовок. Вы можете попробовать cURL и этот фрагмент кода для получения содержимого сайтов:

 $url = 'http://www.alealimay.com'; $c = curl_init($url); curl_setopt($c, CURLOPT_USERAGENT, 'curl/7.48.0'); curl_exec($c); var_dump(curl_getinfo($c)); 

UPD: Нет необходимости использовать cURL для настройки заголовка пользовательского агента. Это также можно сделать с помощью ini_set('user_agent', 'Mozilla/5.0'); а затем функция get_headers будет использовать настроенное значение.