I need to access service running at domain (example.com
) from two different apps running at different ports of localhost but getting CORS error.
PageURL accessed in browser is:
http://localhost:8081/weather
which internally sending AJAX request to
example.com/getResponse
I have CORS header configured in Apache of (example.com
) as follows:
SetEnvIfNocase Origin "http://localhost:8085" CORS_ALLOW_ORIGIN1=$0
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN1}e env=CORS_ALLOW_ORIGIN1
SetEnvIfNocase Origin "http://localhost:8081" CORS_ALLOW_ORIGIN2=$0
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN2}e env=CORS_ALLOW_ORIGIN2
Now Request Headers are:
Accept:*/*
Accept-Encoding: gzip,deflate,br
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Host: example.com
Origin: http://localhost:8081
Referer: http://localhost:8081/weather
User-Agent: Mozilla
Getting Response Header as:
Access-Control-Allow-Origin: $0
Obviously, the error comes back as:
CORS Blocked: Reason: CORS Header does not match '$0'
The presence of Access-Control-Allow-Origin
Header in response means SetEnvIfNoCase
executes and matches the Origin
Request-Header value.
My question is why $0
is not getting replaced by the whole string getting matched?
My question is why
$0
is not getting replaced by the whole string getting matched.?
This is bug-like1 (IMO) behaviour of the SetEnvIf[NoCase]
directive. In situations when the 2nd argument doesn't "look like" a regex, the entire match is not captured, no backreferences are generated, and instead $0
is seen as a literal string.
It is preferable to be explicit and include a capturing group (parenthesised subpattern) and use the $1
backreference instead.
For example:
SetEnvIfNocase Origin "^(http://localhost:8085)" CORS_ALLOW_ORIGIN1=$1
1 Or maybe an optimisation?! It behaves like a simple substring().
Aside:
SetEnvIfNocase Origin "http://localhost:8085" CORS_ALLOW_ORIGIN1=$0 Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN1}e env=CORS_ALLOW_ORIGIN1 SetEnvIfNocase Origin "http://localhost:8081" CORS_ALLOW_ORIGIN2=$0 Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN2}e env=CORS_ALLOW_ORIGIN2
It's not clear why you would need two expressions (and two variables) here, since these are mutually exclusive events. For example, the same result would be achieved with the following:
SetEnvIf Origin "^(http://localhost:808[51])" CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
(A case-insensitive match would also seem to be redundant here.)