Существует ли $ _SERVER в PHP или нет?

По всему Интернету, включенному даже здесь, в Stack Overflow, люди заявляют, что хороший способ проверить, является ли запрос AJAX или нет, это сделать следующее:

if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {...} 

Тем не менее, я не вижу $_SERVER['HTTP_X_REQUESTED_WITH'] в официальной документации PHP

И когда я пытаюсь сделать следующее:

 echo $_SERVER['HTTP_X_REQUESTED_WITH']; 

Ничего не выводится.

Я делаю что-то неправильно? Потому что я действительно хотел бы иметь возможность использовать $_SERVER['HTTP_X_REQUESTED_WITH'] если он доступен.

Переменные в $_SERVER не являются частью PHP, поэтому вы не найдете их в документации PHP. Они подготовлены веб-сервером, который передает их на язык сценариев.

Насколько мне известно, X-Requested-With отправляется функциями Ajax большинства основных Framework, но не все (например, Dojo добавили его всего два года назад: # 5801 ). Как таковой, и принимая во внимание комментарии @bobince, можно с уверенностью сказать, что обычно это не 100% надежный способ определить, является ли запрос AJAX-запросом или нет.

Единственным 100% -ным безопасным способом является отправка заранее определенного флага (например, GET-переменной) вместе с запросом и для страницы-получателя для проверки наличия этого флага.

не забывайте, что вы можете легко обмануть любой заголовок с помощью cURL

 curl_setopt($ch,CURLOPT_HTTPHEADER,array("X-Requested-With : XMLHttpRequest")); 

Клавиши $_SERVER которые начинаются с HTTP_ , генерируются из заголовков HTTP-запросов. В этом случае заголовок X-Requested-With .

Этот заголовок является стандартизированным процессом из всех библиотек AJAX.

Он не будет задокументирован в документации php per se, а скорее в разных библиотеках AJAX, которые устанавливают этот заголовок. Общие библиотеки отправляют этот заголовок: jQuery, Mojo, Prototype, …

Обычно эта библиотека устанавливает заголовок, используя

 xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

Вот быстрая функция с примером использования:

 function isXmlHttpRequest() { $header = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? $_SERVER['HTTP_X_REQUESTED_WITH'] : null; return ($header === 'XMLHttpRequest'); } // example - checking our active call if(!isXmlHttpRequest()) { echo 'Not an ajax request'; } else { echo 'is an ajax request'; } 
 echo $_SERVER['HTTP_X_REQUESTED_WITH']; 

Что вы ожидаете от такого кода? Предположим, что вы запускаете его непосредственно из браузера, не используя запрос AJAX. Итак, как же этот заголовок может быть установлен?

Ну, ответ на окончательный вопрос о жизни, Вселенной и обо всем – сниффер HTTP ! Получите себя и забудьте распечатать переменную $ _SERVER.

У Firebug есть один или вы можете использовать прокси-сервер Fiddler HTTP или плагин LiveHTTPHeaders Mozilla. Мне скучно делать ссылки, но это легко googled.

Таким образом, с помощью HTTP-сниффер вы можете быть уверены в каком-либо HTTP-заголовке.

Обратите внимание, что вы не можете предотвратить «прямой доступ» с помощью XHR, так как каждый HTTP-запрос на ваш сервер уже «прямо».

Вы также можете обвинить некоторые ошибки браузера – см. Этот вопрос и его решение для Firefox

Firefox не сохраняет пользовательские заголовки во время перенаправления запроса Ajax: решение ASP.NET MVC

IE также имеет проблему кэширования, которая является более серьезной, чем обнаружение метода запроса.

В любом случае вам нужно добавить кэш-серверы, чтобы избежать кэширования, поэтому почему бы не использовать другой флаг для указания вызова ajax – или лучше, вы можете использовать другой URL-адрес, например http://ajax.mysite.com/endpoint/sevice?params

 $headers = apache_request_headers(); $is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest'); 

Лучшее решение, чтобы убедиться, что HTTP-запрос действительно отправлен через AJAX, использует проверку SESSION, вы отправляете session_id в параметр get, и вы проверяете этот сеанс, если это разрешено или нет!

Я согласен с Пеккой. Не существует надежного нативного метода между передней и задней сторонами, которые могут автоматически определять, действительно ли клиент вызывает конечную точку с использованием AJAX.

Для моего собственного использования у меня есть несколько основных способов проверить, запрашивает ли клиент одну из моих конечных точек:

  1. Я могу использовать HTTP_X_REQUESTED_WITH, когда я не в контексте перекрестного домена.

  2. вместо проверки «X-request-with», я проверяю $ _SERVER ['HTTP_ORIGIN'] (который отправляется из запроса AJAX), намереваясь обрабатывать междоменные разрешения. Большая часть времени, основная причина, по которой я проверяю, является ли запрос AJAX-запросом, особенно из-за перекрестных доменных разрешений, используя этот заголовок PHP code: 'Access-Control-Allow-Origin:'. $ _ SERVER [' HTTP_ORIGIN ']); // Если этот «HTTP_ORIGIN» находится в моем белом списке

  3. мои API ждут от клиента явного, в нескольких случаях, типа данных (JSON, HTML и т. д.) в GET или POST var. Например, я проверяю, не является ли $ _REQUEST ['ajax'] пустым или равным ожидаемому значению.