Skip to content

Illustrates CORS preflight and impact of Access-Control-Max-Age header.

License

Notifications You must be signed in to change notification settings

gabrielweyer/cors

Repository files navigation

CORS

Build Status

Hosted at https://salmon-pond-0870a1e00.2.azurestaticapps.net/.

Illustrates different scenarios related to CORS:

  • A preflight request with the server responding without any CORS headers
  • A preflight request with the server responding with all the expected CORS headers with the exception of Access-Control-Max-Age
  • Preflight requests with the server responding with all the expected CORS headers including Access-Control-Max-Age
    • Use a different path and query string to demonstrate the impact on the cache

🚨 ensure that Disable cache is unchecked in the Network Developer Tools, otherwise the preflight requests will not be cached.

Without any CORS headers

Preflight request for NoCors

  • URL: https://cors-func.azurewebsites.net/no-cors
  • Method: OPTIONS

Relevant preflight request headers:

access-control-request-headers: authorization
access-control-request-method: GET
origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Relevant preflight response headers:

None

Preflight result for NoCors

The preflight fails as the response does not contain a Access-Control-Allow-Origin header. See the output of the Chrome console below:

Access to XMLHttpRequest at 'https://cors-func.azurewebsites.net/no-cors' from origin 'https://salmon-pond-0870a1e00.2.azurestaticapps.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

With CORS headers (but without Access-Control-Max-Age)

Preflight request for CorsNoCache

  • URL: https://cors-func.azurewebsites.net/cors-no-cache
  • Method: OPTIONS

Relevant preflight request headers:

access-control-request-headers: authorization
access-control-request-method: GET
origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Relevant preflight response headers:

access-control-allow-credentials: true
access-control-allow-headers: authorization
access-control-allow-method: GET
access-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Preflight result for CorsNoCache

The preflight succeeds and Chrome then issue the GET request.

GET request for CorsNoCache

  • URL: https://cors-func.azurewebsites.net/cors-no-cache
  • Method: GET

Relevant GET request headers:

authorization: Bearer TopSecret
origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Relevant GET response headers:

access-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

GET result for CorsNoCache

The GET succeeds and returns the content of the Authorization header (super secure I know):

{"authorization":"Bearer TopSecret"}

Note: each subsequent GET call requires a preflight request:

One preflight per GET

With CORS headers (and with Access-Control-Max-Age)

Preflight request for CorsCache

  • URL: https://cors-func.azurewebsites.net/cors-cache
  • Method: OPTIONS

Relevant preflight request headers:

access-control-request-headers: authorization
access-control-request-method: GET
origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Relevant preflight response headers:

access-control-allow-credentials: true
access-control-allow-headers: authorization
access-control-allow-method: GET
access-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net
access-control-max-age: 600

Preflight result for CorsCache

The preflight succeeds and Chrome then issue the GET request.

GET request for CorsCache

  • URL: https://cors-func.azurewebsites.net/cors-cache
  • Method: GET

Relevant GET request headers:

authorization: Bearer TopSecret
origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

Relevant GET response headers:

access-control-allow-origin: https://salmon-pond-0870a1e00.2.azurestaticapps.net

GET result for CorsCache

The GET succeeds and returns the content of the Authorization header (super secure I know):

{"authorization":"Bearer TopSecret"}

Note: subsequent GET calls do not issue preflight requests:

Single preflight

This is true as long as the result of the initial preflight is cached. Access-Control-Max-Age is capped by a maximum value for each browser:

  • 24 hours for Firefox
  • 2 hours for Chromium (10 minutes for v75 and prior)

The initial preflight is only cached for the same path and query string.