Comment ajouter Access-Control-Allow-Origin dans NGINX?


158

Comment définir l'en-tête Access-Control-Allow-Origin pour pouvoir utiliser les polices Web de mon sous-domaine sur mon domaine principal?


Remarques:

Vous trouverez des exemples de cela et d'autres en-têtes pour la plupart des serveurs HTTP dans les projets HTML5BP Server Configs https://github.com/h5bp/server-configs


4
ah a finalement trouvé l'emplacement de la réponse / {add_header Access-Control-Allow-Origin "*"; }
Chris McKee

Réponses:


183

Nginx doit être compilé avec http://wiki.nginx.org/NginxHttpHeadersModule (par défaut sur Ubuntu et certaines autres distributions Linux). Alors tu peux faire ça

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

Suivez ces instructions si vous souhaitez implémenter la même solution sur apache: stackoverflow.com/questions/11616306/…
camilo_u

6
Ce module semble être compilé par défaut (au moins sur Ubuntu).
Steve Bennett

1
également compilé par défaut sur Amazon Linux repo
Ross

1
Dans quel fichier et emplacement nous devrions mettre cette directive location?
Sumit Arora

1
Ca ne marche pas pour moi Nginx 1.10.0, Ubuntu 16.04
Omid Amraei 17/06/2017

36

Une réponse plus à jour:

#
# 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

Vous pouvez également souhaiter ajouter Access-Control-Expose-Headers(au même format que les en-têtes Access-Control-Allow-Allow) afin d'exposer vos en-têtes personnalisés et / ou "non simples" aux demandes 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/

Configurations pour d'autres serveurs Web http://enable-cors.org/server.html


1
Un moyen de ne pas avoir à répéter ces lignes pour chaque emplacement? Pouvons-nous le placer sous le bloc serveur {}?
geoyws

@geoyws (sans le @ je n'ai pas reçu de notification); vous pourriez le mettre au-dessus de l'emplacement, c'est très bien :)
Chris McKee

Les contrôles d'accès-contrôle-exposer sont manquants ici
chovy

3
S'il vous plaît éviter d'utiliser ifin nginx - même le manuel officiel le décourage .
agrégat1166877

1
J'aimerais ajouter qu'il est utile d'ajouter une alwaysoption à tous add_headerafin que les en-têtes soient ajoutés également pour les réponses autres que 200. Depuis nginx 1.7.5: nginx.org/en/docs/http/ngx_http_headers_module.html
Mitar le

11

Voici l'article que j'ai écrit et qui évite une partie de la duplication pour GET | POST. Cela devrait vous aider avec CORS à Nginx.

Le contrôle d'accès nginx autorise l'origine

Voici l'extrait extrait du message:

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
Conformément à la politique de la SF, vous devez copier les informations dans le message, pas seulement les relier. Les sites Web peuvent disparaître à tout moment, ce qui entraînerait une perte d'informations.
Tim

1
Point valide @tim, mis à jour pour inclure le code
gansbrest le

Pensez à utiliser le code d'état 204 No contentcar cela semble plus approprié.
Slava Fomin II le

7

Tout d’abord, laissez-moi vous dire que @hellvinz answer travaille pour moi:

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

Cependant, j'ai décidé de répondre à cette question par une réponse distincte, car je n'ai réussi à faire fonctionner cette solution qu'après une dizaine d'heures supplémentaires à la recherche d'une solution.

Il semble que Nginx ne définisse aucun type (correct) MIME de police par défaut. En suivant ce monument, j'ai trouvé que je pouvais ajouter ce qui suit:

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

À mon etc/nginx/mime.typesdossier. Comme indiqué, la solution ci-dessus a ensuite fonctionné.


2
Je signale habituellement les gens pour vérifier le fichier de type MIME sur H5BP github.com/h5bp/server-configs-nginx/blob/master/mime.types~~V~~singular~~3rd :)
Chris McKee

4

La directive add_header traditionnelle de Nginx ne fonctionne pas avec les réponses 4xx. Comme nous voulons toujours leur ajouter des en-têtes personnalisés, nous devons installer le module ngx_headers_more pour pouvoir utiliser la directive more_set_headers, qui fonctionne également avec les réponses 4xx.

sudo apt-get install nginx-extras

Ensuite, utilisez more_set_headers dans le fichier nginx.conf, j'ai collé mon échantillon ci-dessous

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

Dans certains cas, vous devez utiliser des add_headerdirectives avec alwayspour couvrir tous les codes de réponse HTTP.

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

De la documentation :

Si le paramètre always est spécifié (1.7.5), le champ d'en-tête sera ajouté quel que soit le code de réponse.

Ajoute le champ spécifié à un en-tête de réponse à condition que le code de réponse soit égal à 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13) ou 308 (1.13 .0) La valeur du paramètre peut contenir des variables.


0

Dans mon cas, avec Rails 5, la seule solution efficace a été d’ajouter la rack-corsgemme. Ainsi:

dans / Gemfile

# Gemfile
gem 'rack-cors'

dans 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

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


Comment cela aide-t-il Nginx à servir des fichiers statiques?
Walf

J'utilisais nginx en tant que proxy inverse pour desservir l'application rails 5. Il s'agit d'un cas particulier où la restriction CORS ne provenait pas de nginx mais de l'application Rails d'origine située derrière.
user9869932
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.