Come faccio ad aggiungere Access-Control-Allow-Origin in NGINX?


158

Come posso impostare l'intestazione Access-Control-Allow-Origin in modo da poter usare i font web dal mio sottodominio sul mio dominio principale?


Appunti:

Troverai esempi di questa e altre intestazioni per la maggior parte dei server HTTP nei progetti di configurazione del server HTML5BP https://github.com/h5bp/server-configs


4
ah finalmente trovato la posizione della risposta / {add_header Access-Control-Allow-Origin "*"; }
Chris McKee,

Risposte:


183

Nginx deve essere compilato con http://wiki.nginx.org/NginxHttpHeadersModule (impostazione predefinita su Ubuntu e alcune altre distribuzioni Linux). Quindi puoi farlo

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

Seguire queste istruzioni nel caso in cui si desidera desidera implementare la stessa soluzione su Apache: stackoverflow.com/questions/11616306/...
camilo_u

6
Quel modulo sembra essere compilato di default (almeno su Ubuntu).
Steve Bennett,

1
compilato anche di default sul repository linux di Amazon
Ross

1
In quale file e posizione dovremmo inserire questa direttiva sulla posizione?
Sumit Arora,

1
Non funziona per me. Nginx 1.10.0, Ubuntu 16.04
Omid Amraei,

36

Una risposta più aggiornata:

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

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

Potresti anche voler aggiungere Access-Control-Expose-Headers(nello stesso formato di Access-Control-Allow-Headers) per esporre le tue intestazioni personalizzate e / o "non semplici" a richieste 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/

Configurazioni per altri server Web http://enable-cors.org/server.html


1
Un modo per non dover ripetere queste righe per ogni posizione? Possiamo metterlo sotto il blocco del server {}?
geoyws,

@geoyws (senza @ non ho ricevuto una notifica); potresti metterlo sopra la posizione, va bene :)
Chris McKee,

mancano qui access-control-expose-headers
chovy

3
Si prega di evitare l'uso ifin nginx - anche il manuale ufficiale lo scoraggia .
aggregato

1
Vorrei aggiungere che è utile aggiungere alwaysun'opzione a tutti in add_headermodo che le intestazioni vengano aggiunte anche per le risposte non 200. Da nginx 1.7.5: nginx.org/en/docs/http/ngx_http_headers_module.html
Mitar

11

Ecco l'articolo che ho scritto che evita alcune delle duplicazioni per GET | POST. Dovrebbe iniziare con CORS in Nginx.

il controllo di accesso nginx consente l'origine

Ecco lo snippet di esempio dal 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
    ....
  }
}

2
Secondo la politica SF è necessario copiare le informazioni nel post, non solo un link ad esso. I siti Web possono scomparire in qualsiasi momento, con conseguente perdita di informazioni.
Tim

1
Punto valido @tim, aggiornato per includere il codice
gansbrest,

Prendi in considerazione l'utilizzo del codice di stato 204 No contentin quanto sembra più appropriato.
Slava Fomin II

7

Innanzitutto, lasciami dire che la risposta di @hellvinz funziona per me:

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

Tuttavia, ho deciso di rispondere a questa domanda con una risposta separata poiché sono riuscito a far funzionare questa soluzione solo dopo aver impiegato circa altre dieci ore alla ricerca di una soluzione.

Sembra che Nginx non definisca alcun tipo MIME (corretto) per impostazione predefinita. Seguendo questo tutorial ho scoperto che potrei aggiungere quanto segue:

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

Nel mio etc/nginx/mime.typesfile. Come detto, la soluzione sopra ha funzionato.


2
Di solito suggerirei alle persone di controllare il file del tipo mime su H5BP github.com/h5bp/server-configs-nginx/blob/master/mime.types :)
Chris McKee,

4

La tradizionale direttiva add_header di Nginx non funziona con le risposte 4xx. Dato che vogliamo ancora aggiungere intestazioni personalizzate, è necessario installare il modulo ngx_headers_more per poter utilizzare la direttiva more_set_headers, che funziona anche con le risposte 4xx.

sudo apt-get install nginx-extras

Quindi utilizzare more_set_headers nel file nginx.conf, ho incollato il mio esempio di seguito

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

1

In alcuni casi è necessario utilizzare le add_headerdirettive con alwaysper coprire tutti i codici di risposta HTTP.

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

Dalla documentazione :

Se viene specificato il parametro always (1.7.5), il campo di intestazione verrà aggiunto indipendentemente dal codice di risposta.

Aggiunge il campo specificato a un'intestazione di risposta a condizione che il codice di risposta sia uguale a 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13) o 308 (1.13 0,0). Il valore del parametro può contenere variabili.


0

Nel mio caso, usando Rails 5, l'unica soluzione funzionante è stata l'aggiunta della rack-corsgemma. Così:

in / Gemfile

# Gemfile
gem 'rack-cors'

in config / initializer / 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

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


come può aiutare nginx a servire file statici?
Walf

Stavo usando nginx come proxy inverso per servire l'app rails 5. Questo è un caso particolare in cui la restrizione CORS non proveniva da nginx ma dall'app Rails di origine dietro di essa.
user9869932,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.