To fully CORS-enable an Apache web server, you need to have it configured to look like this:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Authorization"
Header always set Access-Control-Allow-Methods "GET"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Max-Age "600"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
Longer explanation at https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/
Some general notes on what values to set for the various Access-Control-
response headers:
-
Access-Control-Allow-Headers
: you must set it to include any header names your request sends except CORS-safelisted header names or so-called “forbidden” header names (names of headers set by the browser that you can’t set in your JavaScript); the spec alternatively allows the*
wildcard as its value—so you can try it, though some browsers may not support it yet: Chrome bug, Firefox bug, Safari bug. -
Access-Control-Allow-Methods
: the spec alternatively allows the*
wildcard—but again, as withAccess-Control-Allow-Headers: *
, some browsers may not support it yet. -
Access-Control-Expose-Headers
: set to include any response headers beyondExpires
,Cache-Control
,Content-Type
,Pragma
,Last-Modified
, andContent-Language
that your frontend code needs to read. A lot of people forget to set this and end up baffled about why they can’t read the value of a particular response header). Again the spec alternatively allows the*
wildcard here, but some browsers may not support it yet. -
Access-Control-Max-Age
: Chrome has an upper limit of600
(10 minutes) hardcoded, so there’s no point in setting a higher value for it than that (Chrome will just throttle it down to 10 minutes if you set it higher, and Safari limits it to only 5 minutes).
So then, about the particular request shown in the question, the specific changes and additions that would need to made are these:
-
Use
Header always set
instead of justHeader set
. -
Use mod_rewrite to handle the
OPTIONS
by just sending back200 OK
with those headers. -
The request has
Access-Control-Request-Headers:authorization
so in the Apache config, addAuthorization
in theAccess-Control-Allow-Headers
response header too. -
Origin
is a “forbidden” header name set by the browser, andAccept
is a CORS-safelisted header name, so no need to include them inAccess-Control-Allow-Headers
. -
The request sends no
Content-Type
, so no need for it inAccess-Control-Allow-Headers
in the response (and never needed forGET
requests and otherwise only needed if the type is notapplication/x-www-form-urlencoded
,text/plain
, ormultipart/form-data
). -
For
Access-Control-Allow-Methods
, the request seems to just be aGET
, so unless the plan’s to also makePOST
/PUT
/DELETE
/PATCH
requests, no point in including them.