Bagaimana cara menambahkan Access-Control-Allow-Origin di NGINX?

158

Bagaimana cara mengatur tajuk Akses-Kontrol-Bolehkan-Asal agar saya dapat menggunakan font web dari subdomain saya di domain utama saya?


Catatan:

Anda akan menemukan contoh ini dan header lain untuk sebagian besar server HTTP di proyek Konfigurasi Server HTML5BP https://github.com/h5bp/server-configs

Chris McKee
sumber
4
ah akhirnya menemukan lokasi jawaban / {add_header Access-Control-Allow-Origin "*"; }
Chris McKee
ng4free.com/...
Jaydeep Gondaliya

Jawaban:

183

Nginx harus dikompilasi dengan http://wiki.nginx.org/NginxHttpHeadersModule (default pada Ubuntu dan beberapa distro Linux lainnya). Maka Anda bisa melakukan ini

location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}
hellvinz
sumber
Ikuti instruksi ini jika Anda ingin menerapkan solusi yang sama pada apache: stackoverflow.com/questions/11616306/…
camilo_u
6
Modul itu tampaknya dikompilasi secara default (setidaknya di Ubuntu).
Steve Bennett
1
juga dikompilasi secara default di repo linux amazon
Ross
1
Di file dan lokasi mana kita harus meletakkan arahan lokasi ini?
Sumit Arora
1
Itu tidak bekerja untuk saya. Nginx 1.10.0, Ubuntu 16.04
Omid Amraei
36

Jawaban yang lebih terkini:

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

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

Anda juga dapat menambahkan Access-Control-Expose-Headers(dalam format yang sama dengan Header Akses-Kontrol-Bolehkan) untuk mengekspos header kustom Anda dan / atau 'tidak sederhana' ke permintaan 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/

Konfigurasi untuk server web lain http://enable-cors.org/server.html

Chris McKee
sumber
1
Adakah cara untuk tidak mengulangi garis-garis ini untuk setiap lokasi? Bisakah kita meletakkannya di bawah blok server {}?
geoyws
@geoyws (tanpa @ Saya tidak mendapatkan pemberitahuan); Anda bisa meletakkannya di atas lokasi, itu baik-baik saja :)
Chris McKee
access-control-expose-header tidak ada di sini
chovy
3
Harap hindari penggunaan ifdi nginx - bahkan manual resmi tidak menyarankannya .
aggregate1166877
1
Saya ingin menambahkan bahwa berguna untuk menambahkan alwaysopsi ke semua add_headersehingga tajuk ditambahkan juga untuk respons non-200. Sejak nginx 1.7.5: nginx.org/en/docs/http/ngx_http_headers_module.html
Mitar
11

Inilah artikel yang saya tulis yang menghindari beberapa duplikasi untuk GET | POST. Seharusnya Anda menggunakan CORS di Nginx.

kontrol akses nginx memungkinkan asal

Berikut cuplikan sampel dari pos:

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
sumber
2
Sesuai kebijakan SF, Anda perlu menyalin informasi ke dalam pos, bukan hanya menautkannya. Situs web dapat menghilang kapan saja, yang akan menyebabkan hilangnya informasi.
Tim
1
Poin valid @tim, diperbarui untuk memasukkan kode
gansbrest
Pertimbangkan untuk menggunakan kode status 204 No contentkarena tampaknya lebih sesuai.
Slava Fomin II
7

Pertama, izinkan saya mengatakan bahwa jawaban @hellvinz bekerja untuk saya:

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

Namun, saya telah memutuskan untuk menjawab pertanyaan ini dengan jawaban yang terpisah karena saya hanya berhasil membuat solusi ini berfungsi setelah menghabiskan sekitar sepuluh jam lagi mencari solusi.

Tampaknya Nginx tidak mendefinisikan jenis font MIME (benar) secara default. Dengan mengikuti pelajaran ini saya menemukan saya dapat menambahkan yang berikut:

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

Ke etc/nginx/mime.typesfile saya . Sebagaimana dinyatakan, solusi di atas kemudian bekerja.

DazBaldwin
sumber
2
Saya biasanya mengarahkan orang untuk memeriksa file tipe mime pada H5BP github.com/h5bp/server-configs-nginx/blob/master/mime.types :)
Chris McKee
4

Arahan add_header tradisional Nginx tidak bekerja dengan respons 4xx. Karena kami masih ingin menambahkan custom header ke dalamnya, kami perlu menginstal modul ngx_headers_more untuk dapat menggunakan direktif more_set_headers, yang juga berfungsi dengan respons 4xx.

sudo apt-get install nginx-extras

Kemudian gunakan more_set_headers dalam file nginx.conf, saya telah menempelkan sampel saya di bawah ini

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;
    }
}
Hasn Safder
sumber
1

Dalam beberapa kasus, Anda perlu menggunakan add_headerarahan dengan alwaysuntuk mencakup semua kode respons HTTP.

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

Dari dokumentasi :

Jika parameter selalu ditentukan (1.7.5), bidang header akan ditambahkan terlepas dari kode respons.

Menambahkan bidang yang ditentukan ke header respons dengan ketentuan bahwa kode respons sama dengan 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), atau 308 (1.13 .0). Nilai parameter dapat berisi variabel.

laimison
sumber
0

Dalam kasus saya, menggunakan Rails 5, satu-satunya solusi yang berhasil adalah menambahkan rack-corspermata. Seperti itu:

di / Gemfile

# Gemfile
gem 'rack-cors'

di 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

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

pengguna9869932
sumber
bagaimana itu membantu nginx melayani file statis?
Walf
Saya menggunakan nginx sebagai proxy terbalik untuk melayani aplikasi rails 5. Ini adalah kasus khusus di mana pembatasan CORS bukan berasal dari nginx tetapi dari App Rails asli di belakangnya.
user9869932