$ _SERVER ['HTTP_X_REQUESTED_WITH'] существует в PHP или нет? - PullRequest
66 голосов
/ 05 апреля 2010

По всему Интернету, включая даже здесь, в 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'], если он доступен.

Ответы [ 10 ]

60 голосов
/ 05 апреля 2010

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

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

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

27 голосов
/ 24 февраля 2011

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

curl_setopt($ch,CURLOPT_HTTPHEADER,array("X-Requested-With : XMLHttpRequest"));
17 голосов
/ 05 апреля 2010

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

12 голосов
/ 05 апреля 2010

Этот заголовок является стандартизацией всех существующих библиотек AJAX.

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

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

xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
4 голосов
/ 26 февраля 2014

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

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';
}
3 голосов
/ 05 апреля 2010
echo $_SERVER['HTTP_X_REQUESTED_WITH'];

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

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

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

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

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

1 голос
/ 25 июня 2014
$headers = apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');
1 голос
/ 10 марта 2011

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

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

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

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

0 голосов
/ 16 августа 2016

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

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

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

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

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

0 голосов
/ 03 января 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...