javascripthttphttpscorsfetch-api

Do browsers not send a CORS preflight request for certain headers added automatically by the browser?


I am using JavaScript's Fetch API like so: fetch(URL)

My browser (Chrome) seems to automatically add If-None-Match and If-Modified-Since headers to the request. Although these headers should trigger preflight requests according to the fetch spec (I think), no preflight requests are being sent. Is this expected when the browser automatically adds such headers rather than me adding it to the fetch function?

I noticed that, when I add If-None-Match and If-Modified-Since headers manually to the fetch function, the browser sends a preflight request:

fetch(cdnUrl, {
  "headers": {
    "If-None-Match": "blah"
  }
})

Solution

  • https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests says that to be classed as a "simple" request - and thus avoid triggering a pre-flight request, a request must meet several conditions, including this one:

    Apart from the headers automatically set by the user agent (for example, Connection, User-Agent, or the other headers defined in the Fetch spec as a forbidden header name), the only headers which are allowed to be manually set are those which the Fetch spec defines as a CORS-safelisted request-header, which are:

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (please note the additional requirements below)
    • Range (only with a simple range header value; e.g., bytes=256- or bytes=127-255)

    Note the phrase

    apart from the headers automatically set by the user agent

    As you've noticed, headers set automatically by the browser do not count as triggering a pre-flight request, and this is expected behaviour.


    IMHO it would be a little unfair to developers if headers set by the browser triggered a pre-flight request - this could potentially break existing code implementations if a browser update suddenly caused extra headers to be send in a fetch request, which then caused a pre-flight request that the server was not expecting. I don't know for sure, but that - plus the fact that such headers are not user-modifiable and therefore represent far less of a problem - would strike me as a good reason for this behaviour.