The following block

location / {
    if ($http_origin ~* (https?://[^/]*\.example\.com(:[0-9]+)?)) {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
    try_files $uri $uri/ /index.php?$args;

… causes a 404 as the above code never reaches the try_files directive, so:

  1. Is this related to the IfIsEvil of nginx?

  2. If it is, then is there some other way to test the http_origin by not using an if statement?

I have tried this with nginx > 1.4 (1.4.6, 1.7, 1.7.8).

  • 1) It's exactly from "if is evil" examples. 2) You could use map or use if outside of location.
    – Alexey Ten
    Mar 12, 2015 at 11:50
  • @AlexeyTen, could you provide an example for how to use if outside the location block? Sep 7, 2016 at 9:18

1 Answer 1


I would use map:

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.example\.com(:[0-9]+)?$" "$http_origin";

server {
    location / {
        add_header Access-Control-Allow-Origin $cors_header;
        try_files $uri $uri/ /index.php;
  • What if the allowed origins need to be different for each server? Apr 5, 2015 at 4:21
  • 3
    Use several maps with different variables
    – Alexey Ten
    Apr 5, 2015 at 10:55
  • I don't think you want several maps. I believe you can just put additional lines in the single map. As you can see in the answer above, there are two lines: one for the default (nginx config defined server) and another for example.com domains. This solution is actually brilliant as you can essentially AllowList a set of domains and nginx will return the Access-Control-Allow-Origin value for the domain that is accessing as long as its in the AllowList.
    – Peter P.
    Jul 30, 2021 at 6:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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