Dalam penyelidikan di bawah ini sebagai API, saya menggunakan http://example.com daripada http: // myApiUrl / login dari pertanyaan Anda, karena ini yang pertama berfungsi.
Saya berasumsi bahwa halaman Anda ada di http: //my-site.local: 8088 .
Alasan mengapa Anda melihat hasil yang berbeda adalah Postman:
- atur tajuk
Host=example.com
(API Anda)
- JANGAN mengatur tajuk
Origin
Ini mirip dengan cara browser mengirim permintaan ketika situs dan API memiliki domain yang sama (browser juga mengatur item header Referer=http://my-site.local:8088
, namun saya tidak melihatnya di Postman). Ketika Origin
tajuk tidak disetel, biasanya server mengizinkan permintaan semacam itu secara default.
Ini adalah cara standar bagaimana Postman mengirim permintaan. Tetapi browser mengirimkan permintaan secara berbeda ketika situs dan API Anda memiliki domain yang berbeda , dan kemudian CORS muncul dan browser secara otomatis:
- set header
Host=example.com
(milik Anda sebagai API)
- set header
Origin=http://my-site.local:8088
(situs Anda)
(Header Referer
memiliki nilai yang sama dengan Origin
). Dan sekarang di tab Konsol & Jaringan Chrome Anda akan melihat:
Ketika Anda memiliki Host != Origin
ini adalah CORS, dan ketika server mendeteksi permintaan semacam itu, biasanya diblokir secara default .
Origin=null
diatur ketika Anda membuka konten HTML dari direktori lokal, dan mengirimkan permintaan. Situasi yang sama adalah ketika Anda mengirim permintaan di dalam <iframe>
, seperti di cuplikan di bawah ini (tapi di sini Host
tajuk tidak disetel sama sekali) - secara umum, di mana pun spesifikasi HTML mengatakan asal buram, Anda dapat menerjemahkannya ke Origin=null
. Informasi lebih lanjut tentang ini dapat Anda temukan di sini .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Jika Anda tidak menggunakan permintaan CORS sederhana, biasanya browser secara otomatis juga mengirimkan permintaan OPSI sebelum mengirim permintaan utama - informasi lebih lanjut ada di sini . Cuplikan di bawah ini menunjukkannya:
fetch('http://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)
Anda dapat mengubah konfigurasi server Anda untuk memungkinkan permintaan CORS.
Berikut adalah contoh konfigurasi yang mengaktifkan CORS pada nginx (file nginx.conf) - sangat berhati-hati dengan pengaturan always/"$http_origin"
untuk nginx dan "*"
untuk Apache - ini akan membuka blokir CORS dari domain apa pun.
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Berikut adalah contoh konfigurasi yang menyalakan CORS di Apache (file .htaccess)
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"
Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"