¿Cómo agrego Access-Control-Allow-Origin en NGINX?

158

¿Cómo configuro el encabezado Access-Control-Allow-Origin para poder usar fuentes web de mi subdominio en mi dominio principal?


Notas:

Encontrará ejemplos de este y otros encabezados para la mayoría de los servidores HTTP en los proyectos de configuraciones de servidor HTML5BP https://github.com/h5bp/server-configs

Chris McKee
fuente
44
ah finalmente encontré la ubicación de respuesta / {add_header Access-Control-Allow-Origin "*"; }
Chris McKee
ng4free.com/…
Jaydeep Gondaliya

Respuestas:

183

Nginx debe compilarse con http://wiki.nginx.org/NginxHttpHeadersModule (predeterminado en Ubuntu y algunas otras distribuciones de Linux). Entonces puedes hacer esto

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}
hellvinz
fuente
Siga estas instrucciones en caso de que quiera implementar la misma solución en apache: stackoverflow.com/questions/11616306/…
camilo_u
66
Ese módulo parece estar compilado por defecto (al menos en Ubuntu).
Steve Bennett
1
también compilado por defecto en Amazon Linux Repo
Ross
1
¿En qué archivo y ubicación debemos poner esta directiva de ubicación?
Sumit Arora
1
A mi no me funciona. Nginx 1.10.0, Ubuntu 16.04
Omid Amraei
36

Una respuesta más actualizada:

#
# 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';
     }
}

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

También es posible que desee agregar Access-Control-Expose-Headers(en el mismo formato que Access-Control-Allow-Headers) para exponer sus encabezados personalizados y / o no simples a las solicitudes de ajax.

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/

Configuraciones para otros servidores web http://enable-cors.org/server.html

Chris McKee
fuente
1
¿Alguna forma de no tener que repetir estas líneas para cada ubicación? ¿Podemos ponerlo debajo del bloque del servidor {}?
geoyws
@geoyws (sin el @ no recibí una notificación); podrías ponerlo encima de la ubicación, está bien :)
Chris McKee
falta acceso-control-exposición-encabezados aquí
chovy
3
Evite usar ifen nginx, incluso el manual oficial lo desalienta .
agregado1166877
1
Me gustaría agregar que es útil agregar la alwaysopción a todos add_headerpara que también se agreguen encabezados para las respuestas que no sean 200. Desde nginx 1.7.5
Mitar
11

Aquí está el artículo que escribí que evita la duplicación de GET | POST. Debería ponerte en marcha con CORS en Nginx.

el control de acceso nginx permite el origen

Aquí está el fragmento de muestra de la publicación:

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
    ....
  }
}
Gansbrest
fuente
2
Según la política de SF, debe copiar la información en la publicación, no solo vincularla. Los sitios web pueden desaparecer en cualquier momento, lo que sería una pérdida de información.
Tim
1
Punto válido @tim, actualizado para incluir el código
gansbrest
Considere usar el código de estado, 204 No contentya que parece más apropiado.
Slava Fomin II
7

En primer lugar, déjame decirte que la respuesta de @hellvinz está funcionando para mí:

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

Sin embargo, he decidido responder a esta pregunta con una respuesta separada, ya que solo logré hacer que esta solución funcionara después de dedicar unas diez horas más a buscar una solución.

Parece que Nginx no define ningún tipo de fuente MIME (correcta) de forma predeterminada. Siguiendo este tuorial descubrí que podía agregar lo siguiente:

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

A mi etc/nginx/mime.typesarchivo Como se indicó, la solución anterior funcionó.

DazBaldwin
fuente
2
Por lo general, les diría a las personas que revisen el archivo de tipo mime en H5BP github.com/h5bp/server-configs-nginx/blob/master/mime.types :)
Chris McKee
4

La directiva add_header tradicional de Nginx no funciona con respuestas 4xx. Como todavía queremos agregarles encabezados personalizados, necesitamos instalar el módulo ngx_headers_more para poder usar la directiva more_set_headers, que también funciona con respuestas 4xx.

sudo apt-get install nginx-extras

Luego use more_set_headers en el archivo nginx.conf, he pegado mi muestra a continuación

server {
    listen 80;
    server_name example-site.com;
    root "/home/vagrant/projects/example-site/public";

    index index.html index.htm index.php;

    charset utf-8;

    more_set_headers 'Access-Control-Allow-Origin: $http_origin';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE, HEAD';
    more_set_headers 'Access-Control-Allow-Credentials: true';
    more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept,Authorization';

    location / {
        if ($request_method = 'OPTIONS') {
            more_set_headers 'Access-Control-Allow-Origin: $http_origin';
            more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE, HEAD';
            more_set_headers 'Access-Control-Max-Age: 1728000';
            more_set_headers 'Access-Control-Allow-Credentials: true';
            more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept,Authorization';
            more_set_headers 'Content-Type: text/plain; charset=UTF-8';
            more_set_headers 'Content-Length: 0';
            return 204;
        }
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/example-site.com-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    location ~ /\.ht {
        deny all;
    }
}
Hasnat Safder
fuente
1

En algunos casos, debe usar add_headerdirectivas alwayspara cubrir todos los códigos de respuesta HTTP.

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

De la documentación :

Si se especifica el parámetro always (1.7.5), el campo de encabezado se agregará independientemente del código de respuesta.

Agrega el campo especificado a un encabezado de respuesta siempre que el código de respuesta sea igual a 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13) o 308 (1.13 .0). El valor del parámetro puede contener variables.

laimison
fuente
0

En mi caso, usando Rails 5, la única solución de trabajo ha sido agregar la rack-corsgema. Al igual que:

en / Gemfile

# Gemfile
gem 'rack-cors'

en config / initializers / cors.rb

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:4200'
    resource '*',
      headers: :any,
      methods: %i(get post put patch delete options head)
  end
end

fuente: https://til.hashrocket.com/posts/4d7f12b213-rails-5-api-and-cors

usuario9869932
fuente
¿Cómo ayuda eso a nginx a servir archivos estáticos?
Walf
Estaba usando nginx como proxy inverso para servir la aplicación rails 5. Este es un caso particular en el que la restricción CORS no provenía de nginx sino de la aplicación Rails de origen detrás de ella.
user9869932