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?
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:
1 Or maybe an optimisation?! It behaves like a simple substring().
Aside:
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:
(A case-insensitive match would also seem to be redundant here.)