Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Wide-open CORS config for nginx
#
# Wide-open CORS config for nginx
#
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
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-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
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-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}

This doesn't seem to work for me ... I'm uisng nginx/1.0.5. For testing I replaced http://10.140.10.40 with *.

Thanks a lot. This saved my day :)

good example for config options

Nek commented May 23, 2012

If only I could see this before wasting 5 hours of time... Thanks a lot for saving the rest of my day! :)

mrdevin commented Aug 2, 2012

For me I hade to return 204 otherwise the browser would hang and then timeout on the option request:
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;

    return 204;
 }
Owner

michiel commented Sep 13, 2012

Updated with 204 return for OPTIONS (mrdevin) and wildcard '*' for Access-Control-Allow-Origin (epicserve).

alexjs commented Nov 28, 2012

I've updated this in https://gist.github.com/4165271 to add a poor man's whitelist. I'm not really sure where having Access-Control-Allow-Origin as wildcard would cause too many issues, but some people may be extra conscious. We use a simple-ish regexp to match valid URLs. Please note that I haven't load tested this, so I don't know what kind of effect it'll have.

remoe commented Dec 18, 2012

Thanks for this. I use:

add_header "Access-Control-Allow-Origin" $http_origin;

FWIW HTTP/1.1 RFC says response from OPTIONS is not cacheable. Doesn't that mean a browser must ignore your Access-Control-Max-Age header?

Thanks a lot!

From MDN:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding.

I've confirmed that at least Firefox will block a request with cookies if the Access-Control-Allow-Origin is set to '*'.

This does not work for me

location / {
             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-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

        root   share/nginx/html;
        proxy_pass         https://dddd.dd.com;
        proxy_set_header   Host dddd.dd.com;  

    }

Meekohi commented Aug 18, 2014

You cannot use a wildcard Access-Control-Allow-Origin if you want to use xhrFields: {withCredentials:true} to send cookies/basicauth. In that case you must use the exact origin:

add_header "Access-Control-Allow-Origin" $http_origin;

When starting to use this Chrome will cache the earlier (CORS failed) requests. Reset the cache to get things working!

TimmyCP commented Sep 20, 2014

Place this in nginx.conf or server blocks?

As stated in the docs add_header does not have any effect on 4xx and 5xx responses.

So save the two hours I just wasted and add always to your add_header (works with nginx 1.7.5+).

brupm commented Jul 1, 2015

By adding this CORS block to my nginx config I now see my initial OPTIONS request followed by an identical GET request (incorrect duplicate) - Any idea what could be causing this?

https://gist.github.com/brupm/1b2c69cbf8f9612ee304

I suspect it's the return 204 line.

niksmac commented Aug 18, 2015

There is a better page http://enable-cors.org/server.html

GromNaN commented Dec 11, 2015

If you use a cache server, you must add a Vary: Origin to the response.

add_header "Access-Control-Allow-Origin" $http_origin;
add_header "Vary" "Origin";

yinyanfr commented Feb 3, 2016

where do i put them?

for anybody on ubuntu first install
sudo apt-get install nginx-extras
and then
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

turn all add_header into more_set_headers
and it will work ;)

rowen17 commented May 17, 2016

On add_header, if your server will intentionally throw status code other than 200, 201, 204, 206, 301, 302, 303, 304, or 307 (Ex. 400 or 422) you should add always on each line

So instead of

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';

Use

add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

Source

maxim25 commented Jun 2, 2016

When I add

add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

I get:
nginx: [emerg] invalid number of arguments in "add_header" directive in /etc/nginx/sites-enabled/foobar:12
nginx: configuration file /etc/nginx/nginx.conf test failed

Any idea?

Skydev0h commented Jun 5, 2016

@maxim25, Are you sure that your nginx is 1.7.5 or newer?

If 'Access-Control-Allow-Credentials' is set "TRUE"
the wildcard (*) in the Allow-Origin dont work!

loustler commented Sep 5, 2016

Thanks.
It is so useful and helpful for me.

Line 28

add_header 'Content-Type' 'text/plain charset=UTF-8';

It seems the semicolon is missing, maybe ' text/plain; charset=UTF-8' is more standard

Cervenka commented Oct 18, 2016

In case you want to use the wildcard origin where possible but also allow credentials if the origin was sent along use following:

set $acac true;
if ($http_origin = ''){
    set $acac false;
    set $http_origin "*";
 }
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials $acac;

x2es commented Oct 24, 2016

why do you specify content-type related headers if no body for 204 response?
https://gist.github.com/michiel/1064640#file-cors-nginx-conf-L28-L29

Here is shorter version of access control allow origin for Nginx that should get you started.

I having problem in this code This giving me error.

defaultwp commented Nov 4, 2017

I have put this code in location inside /site-enabled/ but its still giving error on http://defaultwallpaper.com Please help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment