Detecting AJAX requests with PHP.

This is a guide on how to detect AJAX requests with PHP.

Please note that there is NO sure-fire way of detecting AJAX requests. This is because it is extremely easy to spoof HTTP headers.

In other words, do NOT rely on this code for security.

In the vast majority of cases, JavaScript frameworks and libraries such as JQuery will automatically add the X-Requested-With header to their HTTP requests.

If you use Chrome Developer tools to inspect the AJAX requests that they send, you will find that they set the X-Requested-With header to “XMLHttpRequest“:

X-Requested-With: XMLHttpRequest

This means that you can detect AJAX requests with PHP by checking the HTTP_X_REQUESTED_WITH value in the $_SERVER superglobals array.

Here is a PHP code sample.

<?php

//By default, we assume that it is not
//an AJAX request.
$isAjaxRequest = false;

//IF HTTP_X_REQUESTED_WITH is equal to xmlhttprequest
if(
    isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
    strcasecmp($_SERVER['HTTP_X_REQUESTED_WITH'], 'xmlhttprequest') == 0
){
    //Set our $isAjaxRequest to true.
    $isAjaxRequest = true;
}

Pretty simple, right?

As I said above, you cannot trust this header, as the client can easily set the “xmlhttprequest” value to anything that they want to.

Spoofing AJAX requests with PHP.

Let’s take a look at how easy it is to fake / simulate an AJAX request using cURL and PHP.

<?php

//Initiate cURL and set the URL that we want
//to send a fake AJAX request to.
$ch = curl_init('http://example.com/ajax.php?v=3');

//Set the X-Requested-With header to "XMLHttpRequest"
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "X-Requested-With" => "XMLHttpRequest"
));

//Execute the request.
curl_exec($ch);

See how easy that was? In this case, we were able to change the “X-Requested-With” header to “XMLHttpRequest” using the CURLOPT_HTTPHEADER option.

If I wanted to, I could also spoof the referrer field or modify the User Agent so that the server is fooled into thinking that my simulated XHR request came from a browser.

So be warned! Do not use this type of check for security purposes.