sunting 2018-09-13 : menambahkan beberapa ketentuan tentang permintaan pra-penerbangan ini dan cara menghindarinya di akhir tanggapan ini.
OPTIONS
permintaan adalah apa yang kami sebut pre-flight
permintaan Cross-origin resource sharing (CORS)
.
Mereka diperlukan ketika Anda membuat permintaan di berbagai sumber yang berbeda dalam situasi tertentu.
Permintaan pra-penerbangan ini dibuat oleh beberapa browser sebagai langkah keamanan untuk memastikan bahwa permintaan yang dilakukan dipercaya oleh server. Artinya server memahami bahwa metode, asal, dan tajuk yang dikirim berdasarkan permintaan aman untuk ditindaklanjuti.
Server Anda tidak boleh mengabaikan tetapi menangani permintaan ini setiap kali Anda mencoba melakukan permintaan lintas asal.
Sumber daya yang bagus dapat ditemukan di sini http://enable-cors.org/
Cara untuk menangani ini agar nyaman adalah dengan memastikan bahwa untuk setiap jalur dengan OPTIONS
metode server mengirim respons dengan header ini
Access-Control-Allow-Origin: *
Ini akan memberi tahu browser bahwa server bersedia menjawab permintaan dari asal mana pun.
Untuk informasi lebih lanjut tentang cara menambahkan dukungan CORS ke server Anda, lihat bagan alur berikut
http://www.html5rocks.com/static/images/cors_server_flowchart.png
sunting 2018-09-13
OPTIONS
Permintaan CORS dipicu hanya dalam beberapa kasus, seperti yang dijelaskan dalam dokumen MDN :
Beberapa permintaan tidak memicu preflight CORS. Itu disebut "permintaan sederhana" dalam artikel ini, meskipun spec Fetch (yang mendefinisikan CORS) tidak menggunakan istilah itu. Permintaan yang tidak memicu preflight CORS — yang disebut “permintaan sederhana” —adalah permintaan yang memenuhi semua kondisi berikut:
Satu-satunya metode yang diizinkan adalah:
Terlepas dari tajuk yang ditetapkan secara otomatis oleh agen pengguna (misalnya, Koneksi, Agen-Pengguna, atau tajuk lainnya dengan nama yang ditentukan dalam spesifikasi Ambil sebagai "nama tajuk terlarang"), tajuk satu-satunya yang diizinkan untuk menjadi set manual adalah yang ditentukan oleh spec Fetch sebagai “header-permintaan safelisted-CORS”, yaitu:
- Menerima
- Bahasa Terima
- Konten-Bahasa
- Jenis-Konten (tetapi perhatikan persyaratan tambahan di bawah)
- DPR
- Downlink
- Simpan-Data
- Lebar-viewport
- Lebar
Satu-satunya nilai yang diizinkan untuk header Jenis Konten adalah:
- application / x-www-form-urlencoded
- multipart / formulir-data
- teks / polos
Tidak ada pendengar acara yang terdaftar pada objek XMLHttpRequestUpload apa pun yang digunakan dalam permintaan; ini diakses menggunakan properti XMLHttpRequest.upload.
Tidak ada objek ReadableStream yang digunakan dalam permintaan.
curl
ke api berfungsi, tetapi ketika menjalankan dari chrome saya mendapatkan kesalahan?Origin
header ke permintaan Anda untuk mensimulasikan seolah-olah permintaan tersebut berasal dari host tertentu (misalnya situs web Anda). Anda juga dapat mensimulasikan permintaan preflight dengan mengatur metode HTTP permintaan keOPTIONS
danAccess-Control-*
HeaderTelah melewati masalah ini, di bawah ini adalah kesimpulan saya untuk masalah ini dan solusi saya.
Menurut strategi CORS (sangat disarankan Anda membacanya) Anda tidak bisa memaksa browser untuk berhenti mengirim permintaan OPSI jika menurutnya perlu.
Ada dua cara untuk mengatasinya:
Access-Control-Max-Age
untuk permintaan PILIHANPermintaan sederhana
Permintaan lintas situs sederhana adalah yang memenuhi semua kondisi berikut:
Satu-satunya metode yang diizinkan adalah:
Terlepas dari tajuk yang diatur secara otomatis oleh agen pengguna (mis. Koneksi, Agen-Pengguna, dll.), Satu-satunya tajuk yang diizinkan untuk disetel secara manual adalah:
Satu-satunya nilai yang diizinkan untuk header Jenis Konten adalah:
Permintaan sederhana tidak akan menyebabkan permintaan OPSI pra-penerbangan.
Tetapkan cache untuk pemeriksaan OPSI
Anda dapat menetapkan
Access-Control-Max-Age
untuk permintaan OPSI, sehingga tidak akan memeriksa izin lagi sampai habis.Batasan Tercatat
Access-Control-Max-Age
yaitu600
yang 10 menit, menurut chrome kode sumberAccess-Control-Max-Age
hanya berfungsi untuk satu sumber daya setiap kali, misalnya,GET
permintaan dengan jalur URL yang sama tetapi kueri yang berbeda akan diperlakukan sebagai sumber daya yang berbeda. Jadi permintaan ke sumber daya kedua masih akan memicu permintaan preflight.sumber
Access-Control-Max-Age
. Itulah kuncinya di sini. Ini membantu Anda menghindari permintaan preflight yang berlebihan.application/json
hanya karena itu membuat permintaan Anda menjadi tidak "sederhana" (dan karenanya memicu CORS). Browser sedang melakukan tugasnya. Tetapkan server Anda untuk mengembalikan sesuatu seperti headerAccess-Control-Max-Age: 86400
dan browser tidak akan mengirim ulang permintaan OPSI selama 24 jam.Silakan merujuk jawaban ini pada kebutuhan aktual untuk permintaan OPSI pra-penerbangan: CORS - Apa motivasi di balik memperkenalkan permintaan preflight?
Untuk menonaktifkan permintaan OPSI, kondisi di bawah ini harus dipenuhi untuk permintaan ajax:
application/x-www-form-urlencoded
,multipart/form-data
atautext/plain
Referensi: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
sumber
application/xml
atauapplication/json
bukan "Tajuk HTTP khusus". Header itu sendiriContent-Type
dan memanggil header itu "custom" akan menyesatkan.Ketika Anda memiliki konsol debug terbuka dan
Disable Cache
opsi dihidupkan, permintaan preflight akan selalu dikirim (yaitu sebelum setiap permintaan). jika Anda tidak menonaktifkan cache, permintaan pra-penerbangan hanya akan dikirimkan satu kali (per server)sumber
Ya itu mungkin untuk menghindari permintaan opsi. Permintaan opsi adalah permintaan preflight ketika Anda mengirim (memposting) data apa pun ke domain lain. Ini masalah keamanan browser. Tapi kita bisa menggunakan teknologi lain: lapisan transport iframe. Saya sangat menyarankan Anda melupakan konfigurasi CORS dan menggunakan solusi readymade dan itu akan berfungsi di mana saja.
Lihatlah di sini: https://github.com/jpillora/xdomain
Dan contoh kerja: http://jpillora.com/xdomain/
sumber
Untuk pengembang yang memahami alasan keberadaannya tetapi perlu mengakses API yang tidak menangani panggilan OPSI tanpa auth, saya memerlukan jawaban sementara sehingga saya dapat mengembangkan secara lokal hingga pemilik API menambahkan dukungan SPA CORS yang tepat atau saya mendapatkan API proxy berdiri dan berjalan.
Saya menemukan Anda dapat menonaktifkan CORS di Safari dan Chrome di Mac.
Nonaktifkan kebijakan asal yang sama di Chrome
Chrome: Keluar dari Chrome, buka terminal dan rekatkan perintah ini:
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari: Menonaktifkan kebijakan sumber asli yang sama di Safari
sumber
Seperti yang disebutkan dalam posting sebelumnya,
OPTIONS
permintaan ada karena suatu alasan. Jika Anda memiliki masalah dengan waktu respons yang besar dari server Anda (mis. Koneksi ke luar negeri), Anda juga dapat meminta cache browser Anda terlebih dahulu meminta permintaan.Mintalah server Anda membalas dengan
Access-Control-Max-Age
tajuk dan untuk permintaan yang pergi ke titik akhir yang sama permintaan preflight akan di-cache dan tidak muncul lagi.sumber
OPTIONS
permintaan akan di-cache dengan header ini cukup buram di semua dokumentasi CORS yang saya baca.Saya telah memecahkan masalah ini seperti.
Ini hanya untuk pembangunan. Dengan ini saya menunggu 9ms dan 500ms, bukan 8s dan 500ms. Saya bisa melakukan itu karena aplikasi JS produksi akan berada di mesin yang sama dengan produksi sehingga tidak akan ada
OPTIONS
tetapi pengembangan adalah lokal saya.sumber
Anda tidak bisa tetapi Anda bisa menghindari CORS menggunakan JSONP.
sumber
Setelah menghabiskan satu setengah hari mencoba untuk mengatasi masalah yang sama saya menemukan itu ada hubungannya dengan IIS .
Proyek API Web saya disiapkan sebagai berikut:
Saya tidak memiliki opsi konfigurasi CORS spesifik di web.config> system.webServer node seperti yang saya lihat di banyak posting
Tidak ada kode spesifik CORS di global.asax atau di controller sebagai dekorator
Masalahnya adalah pengaturan kumpulan aplikasi .
Itu modus pipa berhasil ditetapkan untuk klasik ( berubah ke terintegrasi ) dan Identitas ditetapkan untuk Network Service ( berubah ke ApplicationPoolIdentity )
Mengubah pengaturan tersebut (dan menyegarkan kumpulan aplikasi) memperbaikinya untuk saya.
sumber
Apa yang berhasil bagi saya adalah mengimpor "github.com/gorilla/handlers" dan kemudian menggunakannya dengan cara ini:
Segera setelah saya menjalankan permintaan Ajax POST dan melampirkan data JSON ke dalamnya, Chrome akan selalu menambahkan header Tipe Konten yang tidak ada dalam konfigurasi AllowHeaders saya sebelumnya.
sumber
Salah satu solusi yang saya gunakan di masa lalu - katakanlah situs Anda ada di mydomain.com, dan Anda perlu membuat permintaan ajax ke foreigndomain.com
Konfigurasikan penulisan ulang IIS dari domain Anda ke domain asing - mis
di situs mydomain.com Anda - Anda kemudian dapat membuat permintaan asal yang sama, dan tidak perlu untuk permintaan opsi :)
sumber
Ini bisa diselesaikan jika menggunakan proxy yang memotong permintaan dan menulis header yang sesuai. Dalam kasus Varnish khusus ini akan menjadi aturan:
}
sumber
Mungkin ada solusi (tetapi saya tidak mengujinya): Anda dapat menggunakan CSP (Kebijakan Keamanan Konten) untuk mengaktifkan domain jarak jauh Anda dan browser mungkin akan melewatkan verifikasi permintaan PILIHAN CORS.
Saya jika menemukan waktu, saya akan mengujinya dan memperbarui posting ini!
CSP: https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
Spesifikasi CSP: https://www.w3.org/TR/CSP/
sumber