'Detect a fetch request in PHP

How can I detect requests from the Fetch API in PHP? I am currently using the approach below to detect an AJAX request:

$context['isAJAX'] = (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

Ideally I could detect Fetch requests in a similar manner. Does anyone have any techniques to accomplish this?



Solution 1:[1]

There’s no reliable way to distinguish a request made using the Fetch API from one made using XHR or from some AJAX library. The Fetch API doesn’t cause any unique headers to be sent.

If you just want to detect if a request probably came from frontend code running in a browser, you can by checking for the Origin header. Browsers add the Origin header to all cross-origin GETs. So if a GET request was made same-origin from a browser, it won’t have Origin.

And browsers send Origin for same-origin POSTs, not just cross-origin POSTs.

And browsers send Origin for XHR requests too, not just requests from the Fetch API.

So there’s no reliable way to detect on the server side if a request was made with the Fetch API.

Incidentally, if you’re checking for the X-Requested-With request header, all that’ll tell you is, the request was probably made with a common 3rd-party AJAX library instead of directly with XHR or the Fetch API. That’s because X-Requested-With isn’t a standard (that’s why its name starts with X-) and is never sent natively by browsers themselves but is by major libraries.

So I guess if you don’t see the X-Requested-With request header, at least you know that the request probably wasn’t from code using any of the AJAX methods in any of the major libraries, though that just means it also could’ve been sent from curl or something instead of a browser.

And if you see the Origin request header but not the X-Requested-With request then at least you know the request was probably sent from a browser but not using a major library—though there’s some possibility it still could have been sent with curl or whatever, if somebody manually added an Origin header to the request.

Solution 2:[2]

Add to fetch options headers: {'X-Requested-With': 'XMLHttpRequest'}

Solution 3:[3]

Add this:

  fetch(url, {
    headers: {
      'credentials': 'same-origin',
      'X-Requested-With': 'XMLHttpRequest',
      'Content-Type': 'application/json'
       // or 'Content-Type': 'application/x-www-form-urlencoded'
    },
    method: 'POST'
  })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 zardoz
Solution 3 GigolNft