How do I add Access-Control-Allow-Origin in NGINX?

Nginx has to be compiled with http://wiki.nginx.org/NginxHttpHeadersModule (default on Ubuntu and some other Linux distros). Then you can do this

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

wildcard cors

A more up-to-date answer:

#
# 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-CustomHeader,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-CustomHeader,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-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
}

source: https://michielkalkman.com/snippets/nginx-cors-open-configuration.html

You may also wish to add Access-Control-Expose-Headers (in the same format as Access-Control-Allow-Headers) in order to expose your custom and/or 'non-simple' headers to ajax requests.

Access-Control-Expose-Headers (optional) - The XMLHttpRequest 2 object has a 
getResponseHeader() method that returns the value of a particular response 
header. During a CORS request, the getResponseHeader() method can only access 
simple response headers. Simple response headers are defined as follows:
    
    Cache-Control
    Content-Language
    Content-Type
    Expires
    Last-Modified
    Pragma
 If you want clients to be able to access other headers, you have to use the
 Access-Control-Expose-Headers header. The value of this header is a comma-
 delimited list of response headers you want to expose to the client.

-http://www.html5rocks.com/en/tutorials/cors/

Configs for other web servers http://enable-cors.org/server.html


Access-Control-Allow-Credentials

If you're using Access-Control-Allow-Credentials with your CORS request you'll want the cors header wiring within your location to resemble this. As the origin has to match the client domain, wildcard doesn't work.

        if ($http_origin = ''){
            set $http_origin "*";
        }

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

Here is the article that I wrote which avoids some of the duplication for GET|POST. It should get you going with CORS in Nginx.

nginx access control allow origin

Here is the sample snippet from the post:

server {
  listen        80;
  server_name   api.test.com;


  location / {

    # Simple requests
    if ($request_method ~* "(GET|POST)") {
      add_header "Access-Control-Allow-Origin"  *;
    }

    # Preflighted requests
    if ($request_method = OPTIONS ) {
      add_header "Access-Control-Allow-Origin"  *;
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
      add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
      return 200;
    }

    ....
    # Handle request
    ....
  }
}

In some cases you need to use add_header directives with always to cover all HTTP response codes.

location / {
    add_header 'Access-Control-Allow-Origin' '*' always;
}

From documentation:

If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.

Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). Parameter value can contain variables.


Firstly, let me say that @hellvinz answer is working for me:

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

However, I have decided to answer this question with a separate answer as I only managed to get this solution working after putting in about ten more hours looking for a solution.

It seems that Nginx doesn't define any (correct) font MIME types by default. By following this tuorial I found I could add the following:

application/x-font-ttf           ttc ttf;
application/x-font-otf           otf;
application/font-woff            woff;
application/font-woff2           woff2;
application/vnd.ms-fontobject    eot;

To my etc/nginx/mime.types file. As stated, the above solution then worked.