1

I have a wordress page that resolves to /mysite/news and I'm trying to load it onto another site using javascript. This is a natural cors violation so I'm setting cors to * to bypass the issue ONLY if the url is /mysite/news

However, the following isn't working. I suspect REQUEST_URI is actually resolving to something like index.php?page=xxx but I'm not sure. How can I get around this cors issue ?

<If "%{REQUEST_URI} =~ m#news\/?$#">
  Header always set Access-Control-Allow-Origin "*"
  Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
  Header always set Access-Control-Max-Age "1000"
  Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
</If>

1 Answer 1

1

I suspect REQUEST_URI is actually resolving to something like index.php?page=xxx

Yes, it would seem that mod_rewrite is processed before the Apache Expression is evaluated. So, the URL has already been rewritten to index.php (the WordPress front-controller) before we get to evaluate the requested URL in the expression.

However, we can get around this by setting an environment variable "early" using SetEnvif based on the requested URL (which occurs before mod_rewrite) and check for this env var in the expression instead. HOWEVER, an added complication is that this env var is renamed/prefixed with REDIRECT_ after the URL has been rewritten (the first round of processing) to index.php.

For example:

SetEnvIf Request_URI "news/?$" APPLY_CORS
<If "-n reqenv('REDIRECT_APPLY_CORS')">
  Header always set Access-Control-Allow-Origin "*"
  Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
  Header always set Access-Control-Max-Age "1000"
  Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
</If>

SetEnvIf sets the APPLY_CORS env to "1" if the regex matches the request.

The -n operator in the Apache Expression simply tests that the returned string is not empty.


UPDATE: An alternative is to check against THE_REQUEST server variable instead, which contains the first line of the HTTP request (eg. GET /mysite/news HTTP/1.1*1) and does not change as the URL is rewritten. A slight caveat with this is that the regex can be a little more complex.

(*1 - THE_REQUEST contains the raw, %-encoded URI as sent from the client, query string and all.)

For example, an equivalent to the above (which allows for any reasonable query string) would be something like:

<If "%{THE_REQUEST} =~ m#news/?(\?[\w=&-]*)?\s#">
:
</If>
1
  • I've added an alternative solution that uses THE_REQUEST instead - avoids the need for an additonal env var, at the expense of a marginally more complex regex.
    – MrWhite
    Commented Feb 21, 2020 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.