XMLHttpRequest tidak boleh memuatkan XXX, tiada pengepala 'Access-Control-Allow-Origin'
P粉574695215
P粉574695215 2023-09-21 16:34:22
0
2
676

tl;dr; Mengenai polisi asal yang sama

Saya mempunyai proses Grunt yang memulakan contoh pelayan express.js. Ini semua berfungsi dengan baik sehingga tadi, tetapi kini ia mula menyiarkan halaman kosong dan memaparkan perkara berikut dalam log ralat dalam konsol pembangun Chrome (versi terkini):

XMLHttpRequest tidak boleh memuatkan https://www.example.com/ Tiada pengepala 'Access-Control-Allow-Origin' pada sumber yang diminta. Oleh itu, akses daripada 'http://localhost:4300' tidak dibenarkan.

Apakah yang menghalang saya daripada mengakses halaman ini?

P粉574695215
P粉574695215

membalas semua(2)
P粉513316221

Pelayan sasaran mesti membenarkan permintaan merentas domain. Untuk membolehkannya melalui ekspres, hanya kendalikan permintaan pilihan http:

app.options('/url...', function(req, res, next){
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'POST');
   res.header("Access-Control-Allow-Headers", "accept, content-type");
   res.header("Access-Control-Max-Age", "1728000");
   return res.sendStatus(200);
});
P粉953231781

tl;dr — Apabila anda ingin membaca data, (kebanyakannya) menggunakan JS sisi klien, daripada pelayan lain anda memerlukan pelayan dengan data untuk memberikan kebenaran yang jelas kepada kod yang mahukan data. Terdapat ringkasan di hujung dan tajuk dalam jawapan untuk memudahkan mencari bahagian yang berkaitan. Membaca segala-galanya adalah disyorkan walaupun kerana ia menyediakan latar belakang yang berguna untuk memahami

mengapa

yang menjadikan melihat bagaimana bagaimana terpakai dalam keadaan yang berbeza lebih mudah. Mengenai Dasar Asal Yang Sama

Ini adalah

Dasar Asal Yang Sama

. Ia adalah ciri keselamatan yang dilaksanakan oleh pelayar. Kes tertentu anda menunjukkan cara ia dilaksanakan untuk XMLHttpRequest (dan anda akan mendapat hasil yang sama jika anda menggunakan fetch), tetapi ia juga digunakan untuk perkara lain (seperti imej yang dimuatkan ke

), hanya dengan pelaksanaan yang sedikit berbeza .

<canvas> or documents loaded into an <iframe>Senario standard yang menunjukkan keperluan untuk SOP boleh ditunjukkan dengan

tiga aksara

:

Alice ialah seorang yang mempunyai pelayar web
  • Bob menjalankan tapak web (
  • dalam contoh anda)
  • https://www.example.com/Mallory menjalankan tapak web (
  • dalam contoh anda)
  • http://localhost:4300
  • Alice log masuk ke tapak Bob dan mempunyai beberapa data sulit di sana. Mungkin ia adalah intranet syarikat (hanya boleh diakses oleh penyemak imbas di LAN), atau perbankan dalam taliannya (hanya boleh diakses dengan kuki yang anda dapat selepas memasukkan nama pengguna dan kata laluan).

Alice melawat tapak web Mallory yang mempunyai beberapa JavaScript yang menyebabkan penyemak imbas Alice membuat permintaan HTTP ke tapak web Bob (dari alamat IPnya dengan kukinya, dll). Ini boleh jadi semudah menggunakan

.

XMLHttpRequest and reading the responseTextDasar Asal Yang Sama penyemak imbas menghalang JavaScript daripada membaca data yang dikembalikan oleh tapak web Bob (yang Bob dan Alice tidak mahu Mallory akses). (Perhatikan bahawa anda boleh, sebagai contoh, memaparkan imej menggunakan elemen

merentas asal kerana kandungan imej tidak didedahkan kepada JavaScript (atau Mallory) … melainkan anda melemparkan kanvas ke dalam campuran dalam hal ini anda

akan<img> menjana ralat pelanggaran asal yang sama).

Mengapa Polisi Asal yang Sama terpakai apabila anda rasa ia tidak sepatutnya

Untuk mana-mana URL yang diberikan kemungkinan SOP tidak diperlukan. Beberapa senario biasa yang berlaku adalah:

  • Alice, Bob dan Mallory adalah orang yang sama.
  • Bob menyediakan maklumat awam sepenuhnya

… tetapi penyemak imbas tidak mempunyai cara untuk mengetahui sama ada salah satu di atas adalah benar, jadi kepercayaan tidak automatik dan SOP digunakan. Kebenaran perlu diberikan secara jelas sebelum penyemak imbas akan memberikan data yang telah diterima daripada Bob ke beberapa tapak web lain.


Mengapa Dasar Asal yang Sama digunakan pada JavaScript dalam halaman web tetapi sedikit lagi

Di luar laman web

Sambungan penyemak imbas*, tab Rangkaian dalam alat pembangun penyemak imbas dan aplikasi seperti Postman adalah perisian yang dipasang. Mereka tidak menghantar data dari satu tapak web ke JavaScript milik tapak web yang berbeza hanya kerana anda melawati tapak web yang berbeza itu. Memasang perisian biasanya memerlukan pilihan yang lebih sedar.

Tiada pihak ketiga (Mallory) yang dianggap sebagai risiko.

* Sambungan penyemak imbas perlu ditulis dengan teliti untuk mengelakkan isu silang asal. Lihat dokumentasi Chrome sebagai contoh.

Di dalam halaman web

Kebanyakan masa, tidak terdapat banyak kebocoran maklumat apabila hanya menunjukkan sesuatu pada halaman web.

Jika anda menggunakan atribut <img> element to load an image, then it gets shown on the page, but very little information is exposed to Mallory. JavaScript can't read the image (unless you use a crossOrigin untuk mendayakan kebenaran permintaan secara eksplisit dengan CORS) dan kemudian menyalinnya ke pelayannya.

Maksudnya, sesetengah maklumat benar-benar bocor, untuk memetik Domenic Denicola (dari Google):

Inilah sebabnya anda memerlukan kebenaran CORS untuk memuatkan fon merentas asal.


Mengapa anda boleh memaparkan data pada halaman tanpa membacanya dengan JS

Terdapat beberapa keadaan di mana tapak Mallory boleh menyebabkan penyemak imbas mengambil data daripada pihak ketiga dan memaparkannya (cth. dengan menambahkan elemen <img> untuk memaparkan imej). JavaScript Mallory tidak mungkin membaca data dalam sumber itu, hanya penyemak imbas Alice dan pelayan Bob boleh melakukannya, jadi ia masih selamat.


CORS

Pengepala Access-Control-Allow-Origin HTTP respon yang dirujuk dalam mesej ralat adalah sebahagian daripada standard CORS yang membolehkan Bob memberikan kebenaran secara jelas kepada tapak Mallory untuk mengakses data melalui penyemak imbas Alice.

Pelaksanaan asas hanya akan merangkumi:

Access-Control-Allow-Origin: *

… dalam pengepala respons untuk membenarkan mana-mana tapak web membaca data.

Access-Control-Allow-Origin: http://example.com

… akan membenarkan hanya tapak tertentu mengaksesnya dan Bob boleh menjananya secara dinamik berdasarkan pengepala Origin permintaan untuk membenarkan berbilang, tetapi bukan semua, tapak mengaksesnya.

Spesifik cara Bob menetapkan pengepala respons itu bergantung pada pelayan HTTP Bob dan/atau bahasa pengaturcaraan sebelah pelayan. Pengguna Node.js/Express.js harus menggunakan perisian tengah CORS yang didokumentasikan dengan baik. Pengguna platform lain harus melihat koleksi panduan ini untuk pelbagai konfigurasi biasa yang mungkin membantu.

NB: Sesetengah permintaan adalah rumit dan hantar permintaan preflight OPTIONS yang pelayan perlu balas sebelum penyemak imbas akan menghantar GET/POST/PUT/Apa sahaja permintaan yang JS ingin buat. Pelaksanaan CORS yang hanya menambah Access-Control-Allow-Origin pada URL tertentu sering tersandung oleh perkara ini.


Jelas sekali memberikan kebenaran melalui CORS adalah sesuatu yang Bob hanya akan lakukan jika sama ada:

  • Data itu bukan peribadi atau
  • Mallory dipercayai

Bagaimana cara menambah pengepala ini?

Ia bergantung pada persekitaran bahagian pelayan anda.

Jika anda boleh, gunakan perpustakaan yang direka untuk mengendalikan CORS kerana ia akan memberikan anda pilihan mudah dan bukannya perlu berurusan dengan semuanya secara manual.

Enable-Cors.org mempunyai senarai dokumentasi untuk platform dan rangka kerja tertentu yang mungkin berguna untuk anda.

Tetapi saya bukan Bob!

Tiada mekanisme standard untuk Mallory menambah pengepala ini kerana ia mesti datang dari tapak web Bob, yang tidak dikawalnya.

Jika Bob menjalankan API awam maka mungkin terdapat mekanisme untuk menghidupkan CORS (mungkin dengan memformat permintaan dengan cara tertentu, atau pilihan konfigurasi selepas log masuk ke tapak Portal Pembangun untuk tapak Bob). Ini mesti menjadi mekanisme yang dilaksanakan oleh Bob. Mallory boleh membaca dokumentasi di tapak Bob untuk melihat sama ada sesuatu tersedia, atau dia boleh bercakap dengan Bob dan memintanya melaksanakan CORS.


Mesej ralat yang menyebut "Respons for preflight"

Sesetengah permintaan silang asal diterbangkan.

Ini berlaku apabila (secara kasarnya) anda cuba membuat permintaan silang asal bahawa:

  • Termasuk kelayakan seperti kuki
  • Tidak dapat dijana dengan borang HTML biasa (cth. menetapkan Jenis Kandungan yang anda tidak boleh gunakan dalam borang enctype atau beberapa pengepala permintaan lain).

Jika anda melakukan sesuatu dengan betul yang memerlukan penerbangan awal

Dalam kes ini, selebihnya jawapan ini masih terpakai tetapi anda juga perlu memastikan pelayan boleh mendengar permintaan pra-penerbangan (yang akan menjadi OPTIONS (and not GET, POST, or whatever you were trying to send) and respond to it with the right Access-Control-Allow-Origin header but also Access-Control-Allow-Methods and Access-Control-Allow-Headers untuk membenarkan kaedah atau pengepala HTTP khusus anda.

Jika anda tersilap mencetuskan prapenerbangan

Kadang-kadang orang membuat kesilapan apabila cuba membina permintaan Ajax, dan kadangkala ini mencetuskan keperluan untuk penerbangan awal. Jika API direka bentuk untuk membenarkan permintaan silang asal tetapi tidak memerlukan apa-apa yang memerlukan prapenerbangan, maka ini boleh memecahkan akses.

Kesilapan biasa yang mencetuskan ini termasuk:

  • cuba meletakkan Access-Control-Allow-Origin dan tajuk tindak balas CORS lain pada permintaan. Ini tidak sesuai dengan permintaan, jangan lakukan apa-apa yang membantu (apa gunanya sistem kebenaran yang membolehkan anda memberikan kebenaran kepada diri sendiri?), dan mesti dipaparkan hanya pada respons.
  • cuba letak Content-Type: application/json header on a GET request that has no request body the content of which to describe (typically when the author confuses Content-Type and Accept).

Dalam mana-mana kes ini, mengalih keluar pengepala permintaan tambahan selalunya mencukupi untuk mengelakkan keperluan untuk penerbangan awal (yang akan menyelesaikan masalah apabila berkomunikasi dengan API yang menyokong permintaan mudah tetapi bukan permintaan yang dimulakan).


Maklum balas legap (mod no-cors)

Kadangkala anda perlu membuat permintaan HTTP, tetapi anda tidak perlu membaca jawapannya. cth. jika anda menghantar mesej log ke pelayan untuk dirakam.

Jika anda menggunakan the fetch API (rather than XMLHttpRequest), maka anda boleh mengkonfigurasinya untuk tidak cuba menggunakan CORS.

Perhatikan bahawa ini tidak akan membenarkan anda melakukan apa sahaja yang anda perlukan CORS untuk lakukan. Anda tidak akan dapat membaca respons. Anda tidak akan dapat membuat permintaan yang memerlukan prapenerbangan.

Ini akan membolehkan anda membuat permintaan ringkas, tidak melihat respons dan tidak mengisi Konsol Pembangun dengan mesej ralat.

Cara melakukannya dijelaskan oleh mesej ralat Chrome yang diberikan apabila anda membuat permintaan menggunakan fetch dan tidak mendapat kebenaran untuk melihat respons dengan CORS:

Oleh itu:

fetch("http://example.com", { mode: "no-cors" });

Alternatif kepada CORS

JSONP

Bob juga boleh memberikan data menggunakan penggodaman seperti JSONP iaitu cara orang melakukan Ajax silang asal sebelum CORS datang.

Ia berfungsi dengan membentangkan data dalam bentuk program JavaScript yang menyuntik data ke dalam halaman Mallory.

Ia memerlukan Mallory mempercayai Bob untuk tidak memberikan kod hasad.

Perhatikan tema biasa: Tapak yang menyediakan data perlu memberitahu penyemak imbas bahawa adalah OK untuk tapak pihak ketiga mengakses data yang dihantar ke penyemak imbas.

Memandangkan JSONP berfungsi dengan menambahkan elemen <script> untuk memuatkan data dalam bentuk program JavaScript yang memanggil fungsi yang sudah ada dalam halaman, percubaan untuk menggunakan teknik JSONP pada URL yang mengembalikan JSON akan gagal — biasanya dengan ralat CORB — kerana JSON bukan JavaScript.

Alihkan dua sumber kepada satu Asal

Jika dokumen HTML JS dijalankan dan URL yang diminta adalah pada asal yang sama (berkongsi skema, nama hos dan port yang sama) maka Dasar Asal yang Sama memberikan kebenaran secara lalai. CORS tidak diperlukan.

Seorang Proksi

Mallory boleh menggunakan kod sisi pelayan untuk mengambil data (yang kemudiannya boleh dihantar dari pelayannya ke penyemak imbas Alice melalui HTTP seperti biasa).

Ia akan sama ada:

  • tambah pengepala CORS
  • tukar respons kepada JSONP
  • wujud pada asal yang sama dengan dokumen HTML

Kod sebelah pelayan itu boleh ditulis & dihoskan oleh pihak ketiga (seperti CORS Anywhere). Perhatikan implikasi privasi perkara ini: Pihak ketiga boleh memantau siapa yang proksi apa yang merentas pelayan mereka.

Bob tidak perlu memberikan sebarang kebenaran untuk itu berlaku.

Tiada implikasi keselamatan di sini kerana itu hanya antara Mallory dan Bob. Tidak ada cara untuk Bob menganggap Mallory adalah Alice dan memberikan Mallory data yang harus dirahsiakan antara Alice dan Bob.

Oleh itu, Mallory hanya boleh menggunakan teknik ini untuk membaca data awam.

Walau bagaimanapun, ambil perhatian bahawa mengambil kandungan daripada tapak web orang lain dan memaparkannya sendiri mungkin melanggar hak cipta dan membuka anda kepada tindakan undang-undang.

Menulis sesuatu selain apl web

Seperti yang dinyatakan dalam bahagian "Mengapa Dasar Asal Yang Sama hanya terpakai untuk JavaScript dalam halaman web", anda boleh mengelakkan SOP dengan tidak menulis JavaScript dalam halaman web.

Ini tidak bermakna anda tidak boleh terus menggunakan JavaScript dan HTML, tetapi anda boleh mengedarkannya menggunakan beberapa mekanisme lain, seperti Node-WebKit atau PhoneGap.

Sambungan penyemak imbas

Adalah kemungkinan untuk sambungan penyemak imbas menyuntik pengepala CORS dalam respons sebelum Dasar Asal Yang Sama digunakan.

Ini boleh berguna untuk pembangunan tetapi tidak praktikal untuk tapak pengeluaran (meminta setiap pengguna tapak anda memasang sambungan penyemak imbas yang melumpuhkan ciri keselamatan penyemak imbas mereka adalah tidak munasabah).

Mereka juga cenderung berfungsi hanya dengan permintaan mudah (gagal semasa mengendalikan permintaan OPTIONS prapenerbangan).

Mempunyai persekitaran pembangunan yang sesuai dengan pembangunan tempatan pelayan selalunya pendekatan yang lebih baik.


Risiko keselamatan lain

Perhatikan bahawa SOP / CORS tidak mengurangkan serangan XSS, CSRF, atau SQL Injection yang perlu dikendalikan secara bebas.


Ringkasan

  • Tiada apa-apa yang boleh anda lakukan dalam kod sisi pelanggan anda yang akan membolehkan CORS akses kepada pelayan orang lain. Jika anda mengawal pelayan, permintaan sedang dibuat untuk: Menambahkan kebenaran CORS padanya.
  • Jika anda mesra dengan orang yang mengawalnya: Minta mereka menambah kebenaran CORS kepadanya.
  • Jika ia adalah perkhidmatan awam maka (perlu diingat bahawa
  • kebanyakan API pihak ketiga direka bentuk untuk berinteraksi hanya dengan kod sebelah pelayan anda dan tidak menyokong CORS
  • tetapi untuk yang): Baca dokumentasi API mereka untuk melihat apa yang mereka katakan tentang mengaksesnya dengan JavaScript sisi pelanggan:
    • Mereka mungkin memberitahu anda untuk menggunakan URL tertentu
      • Mereka mungkin menyokong JSONP dan bukannya CORS
      • Mereka mungkin tidak menyokong akses silang asal daripada kod pihak pelanggan sama sekali (ini mungkin keputusan yang disengajakan atas alasan keselamatan, terutamanya jika anda perlu menghantar Kunci API diperibadikan dalam setiap permintaan).
      Pastikan anda tidak mencetuskan permintaan prapenerbangan yang anda tidak perlukan. API mungkin memberikan kebenaran untuk permintaan mudah tetapi bukan permintaan yang dimulakan.
    Jika tiada satu pun perkara di atas digunakan: Minta penyemak imbas untuk bercakap dengan pelayan
  • anda
  • , dan kemudian minta pelayan anda mengambil data daripada pelayan lain dan menyampaikannya. (Terdapat juga perkhidmatan dihoskan pihak ketiga yang melampirkan pengepala CORS pada sumber yang boleh diakses secara umum yang boleh anda gunakan).
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan