Nginx Access Control Origin Header is configured but doesn’t work

corsnginx

I am getting a

XMLHttpRequest cannot load http://website2.com/ads/dev_642e92efb79421734881b53e1e1b18b6/5534f8e14d514_1.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://website1.com' is therefore not allowed access.

Website2 is configured using nginx:

server {
listen       80;
server_name  website2.com;
root  /var/www/website2;
index index.php index.html index.htm;
#try_files $uri $uri/ /index.php?$args;

client_max_body_size 20M;
location /ads {
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  try_files $uri $uri/ /index.php?$args;
}
location / {
      try_files $uri $uri/ /index.php?$args;
     # proxy_pass http://127.0.0.1:2368/;
     # proxy_set_header Host $host;
     # proxy_buffering off;
}

  gzip             on;
     gzip_vary        on;
     gzip_types       text/javascript text/css text/xml application/xml application/xml+rss;
     gzip_comp_level  9;
     gzip_min_length  100;
     gzip_buffers 16 8k;
     gzip_proxied     expired no-cache no-store private auth;
     gzip_http_version 1.0;
     gzip_disable     "MSIE [1-6]\.";
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 24h;
        log_not_found off;
    }
    location ~ \.php$ {
      try_files $uri =404;
      # Fix for server variables that behave differently under nginx/php-fpm than typically expected
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      # Include the standard fastcgi_params file included with nginx
      include fastcgi_params;
      fastcgi_param HTTPS $https;
      fastcgi_pass_header X_SECURECONNECTION;
      fastcgi_param  PATH_INFO        $fastcgi_path_info;
      fastcgi_index index.php;
      # Override the SCRIPT_FILENAME variable set by fastcgi_params
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      # Pass to upstream PHP-FPM; This must match whatever you name your upstream connection
      fastcgi_pass 127.0.0.1:9000;
    }
#preventing access to git
    location ~ /\.(?:git).* {
       deny all;
       access_log off;
       log_not_found off;
     }
     #preventing access to .htaccess or htpasswd
     location ~ /\.ht.* {
     deny all;
     access_log off;
     log_not_found off;
    }
    server_tokens off;
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
     return 444;
    }
   location /images/ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
      return   403;
    }
   }

How this webpage is getting requested is by:
1) Accessing a PHP file of website1.
2) The PHP file dies an html webpage which includes javascript files in website2.
3) Javascript uses ajax to get the html in website2 that is not allowed access, it uses the method GET.

The server address is still website1 when the process is over.

I also tried to add it to "location /".

Any ideas?

UPDATE:

After following this:
http://www.html5rocks.com/en/tutorials/cors/

The error was not shown given that add_header 'Access-Control-Allow-Origin' was added to server context, not a location context.

HOWEVER, it frequently does not work. A third or less of the requests still give back the same error:

XMLHttpRequest cannot load http://website2.com/ads/dev_642e92efb79421734881b53e1e1b18b6/5534f8e14d514_1.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://website1.com' is therefore not allowed access.

curl -I shows:

    HTTP/1.1 200 OK
Server: nginx
Date: Wed, 22 Apr 2015 10:30:55 GMT
Content-Type: text/html
Content-Length: 402
Last-Modified: Tue, 21 Apr 2015 09:13:44 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "553614c8-192"
Access-Control-Allow-Origin: *
Accept-Ranges: bytes

Best Answer

There are no proxied requests

Of this block:

location /ads {
    proxy_set_header 'Access-Control-Max-Age' 1728000;
    proxy_set_header 'Access-Control-Allow-Origin' '*';
    proxy_set_header 'Access-Control-Allow-Credentials' 'true';
    proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    proxy_set_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  try_files $uri $uri/ /index.php?$args;
}

The only directive that is doing anything is try_files - because there is no proxied request issued. proxy_pass_header only makes sense if proxy_pass is also used; but it would send the headers to the proxied server, not the client so is irrelevant for CORS.

Use add_header

The directive you're looking for is add_header - a valid example would be:

location /ads {
    add_header "Access-Control-Allow-Origin" "*";
    ...
    try_files $uri $uri/ /index.php?$args;
}

This adds the header to the response sent back to the client (browser).