Panduan

Cara Betulkan Ralat CORS (dan Sebab Ia Berlaku)

Ralat CORS bermaksud halaman web anda cuba membaca respons dari asal yang berbeza (domain, port atau protokol lain), dan pelayan itu tidak menghantar header yang menyatakan ia dibenarkan. Pelayar menyekat respons untuk melindungi pengguna. Anda membetulkannya di pelayan, dengan mengembalikan header Access-Control-Allow-Origin untuk asal laman anda dan mengendalikan permintaan preflight OPTIONS, atau anda mengelaknya dengan menghantar permintaan melalui bahagian belakang anda sendiri pada asal yang sama.

Ia antara ralat yang paling mengelirukan dalam pembangunan web kerana permintaan selalunya sampai ke pelayan dengan baik. Panduan ini menerangkan apa yang berlaku dan cara membetulkan setiap varian.

Apa maksud "asal"

Asal ialah gabungan protokol, domain dan port:

URLAsal
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (subdomain berbeza, jadi asal berbeza)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (port berbeza, jadi asal berbeza)

Pelayar mengikut dasar asal yang sama: JavaScript pada halaman bebas membaca respons dari asalnya sendiri, tetapi tidak dari asal lain. CORS (Cross-Origin Resource Sharing) ialah sistem yang membolehkan pelayan membuat pilihan: “respons daripada saya boleh dibaca oleh halaman dari asal ini.”

Dua akibat yang mengejutkan ramai orang:

  • Permintaan selalunya sampai ke pelayan. CORS biasanya menghalang kod anda daripada membaca respons, bukan menghalang pelayan daripada menerima permintaan. Satu POST mungkin telah disimpan walaupun anda nampak ralat.
  • Hanya pelayar yang menguatkuasakannya. curl, Postman dan kod bahagian pelayan mengabaikan CORS sepenuhnya. Sebab itu “ia berfungsi dalam Postman” tidak memberitahu anda apa-apa tentang CORS.

Langkah 1: Baca ralat tepat

Buka alat pembangun (klik kanan → Inspect), pergi ke Console, dan baca mesej penuh. Perkataan Chrome menunjukkan jenis masalah anda:

Mesej mengandungiApa yang salah
No 'Access-Control-Allow-Origin' header is presentPelayan tidak menghantar header langsung, atau permintaan gagal sebelum mencapai kod CORS anda (contohnya 404 atau 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originPelayan membenarkan asal yang berbeza daripada anda
Response to preflight request doesn't pass access control checkPreflight OPTIONS gagal
...must not be the wildcard '*' when the request's credentials mode is 'include'Anda menghantar kuki, dan pelayan membalas dengan *
Request header field authorization is not allowedPelayan tidak menyenaraikan header itu dalam Access-Control-Allow-Headers

Kemudian buka tab Network, cari permintaan yang gagal (dan sebarang permintaan OPTIONS sebelumnya), dan lihat kod status serta header respons.

Semak kod status dahulu. Banyak “ralat CORS” sebenarnya ralat pelayan yang menyamar. Jika pelayan ranap atau mengembalikan 404, respons ralatnya selalunya tidak mempunyai header CORS, jadi pelayar melaporkan CORS dan bukannya masalah sebenar. Betulkan 500 atau 404, dan ralat CORS mungkin hilang.

Langkah 2: Tentukan sama ada anda perlu memanggil API itu dari pelayar

Sebelum menambah header, tanya: adakah pelayar patut memanggil API ini secara langsung?

  • API pihak ketiga yang memerlukan kunci rahsia (OpenAI, kunci rahsia Stripe, kebanyakan perkhidmatan e-mel) tidak sepatutnya dipanggil dari pelayar. Kunci itu akan kelihatan kepada setiap pelawat. Panggil dari bahagian belakang anda, dan masalah CORS hilang, kerana permintaan pelayan-ke-pelayan tidak tertakluk kepada CORS. Lihat cara memastikan kunci API selamat.
  • API pihak ketiga yang anda tidak kawal dan tidak menghantar header CORS tidak boleh dibetulkan dari pihak anda. Panggil dari bahagian belakang anda.
  • API anda sendiri boleh dibetulkan dengan mengkonfigurasikannya dengan betul. Teruskan di bawah.

Langkah 3: Betulkan pada pelayan anda

Pelayan mesti menambah header yang betul pada setiap respons, termasuk respons ralat.

Untuk permintaan sebenar, hantar:

  • Access-Control-Allow-Origin: https://myapp.com (asal tepat bahagian hadapan anda, tanpa garis miring akhir)
  • Vary: Origin, jika nilainya bergantung pada asal yang meminta

Untuk permintaan preflight OPTIONS, balas dengan status berjaya (200 atau 204) dan:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (setiap header tersuai yang anda hantar)
  • Pilihan Access-Control-Max-Age: 600, supaya pelayar menyimpan preflight dalam cache untuk seketika

Kebanyakan rangka kerja mempunyai pakej atau tetapan yang melakukan ini. Dalam Express, pakej cors; dalam FastAPI, CORSMiddleware; dalam ASP.NET Core, AddCors; dalam Spring, @CrossOrigin atau konfigurasi CORS. Persediaan Express yang tipikal:

import cors from "cors";

app.use(cors({
  origin: ["https://myapp.com", "http://localhost:5173"],
  credentials: true,
}));

Letakkan pengendalian CORS sebelum laluan dan pengesahan anda, supaya permintaan preflight (yang tidak membawa log masuk) tidak ditolak dengan 401.

Dengan pembina AI, terangkan persediaan dengan tepat:

Bahagian hadapan di https://myapp.com memanggil API di https://api.myapp.com dan mendapat "Response to preflight request doesn't pass access control check". Konfigurasikan CORS pada API untuk membenarkan tepat https://myapp.com dan asal pratonton, benarkan GET, POST, PATCH, DELETE dengan header Content-Type dan Authorization, kendalikan OPTIONS sebelum pengesahan, dan sertakan header CORS pada respons ralat juga.

Langkah 4: Kendalikan kuki dan kredensial

Jika bahagian hadapan anda menghantar kuki (contohnya sesi log masuk) ke asal lain, kedua-dua belah mesti bersetuju:

  • Bahagian hadapan menetapkan credentials: "include" pada fetch, atau withCredentials: true pada axios.
  • Pelayan menghantar Access-Control-Allow-Credentials: true.
  • Access-Control-Allow-Origin pelayan mesti asal yang tepat, bukan *.

Kuki merentas tapak juga memerlukan SameSite=None; Secure pada kuki, dan sesetengah pelayar menyekat kuki pihak ketiga dengan lebih ketat. Itu satu lagi sebab untuk mengutamakan pendekatan dalam Langkah 5.

Langkah 5: Elakkan CORS dengan persediaan asal yang sama

Selalunya pembetulan yang paling kemas ialah tidak membuat permintaan merentas asal sama sekali. Hidangkan API dari asal yang sama dengan halaman, contohnya di https://myapp.com/api/...:

  • Dalam pembangunan, kebanyakan pelayan pembangunan boleh memproksi. Pilihan server.proxy Vite boleh memajukan /api ke bahagian belakang anda pada port lain, supaya pelayar hanya bercakap dengan satu asal.
  • Dalam pengeluaran, lalukan /api ke bahagian belakang melalui tetapan rewrite atau proksi hos anda, atau hidangkan bahagian hadapan dan API dari satu pelayan.

Bahagian hadapan kemudian memanggil laluan relatif seperti fetch("/api/orders"). Tiada permintaan merentas asal, tiada preflight merentas asal, dan tiada masalah kuki. Ia juga bermakna anda tidak mengkod keras domain API yang berbeza antara pratonton dan pengeluaran.

Tukar bahagian hadapan untuk memanggil bahagian belakang dengan laluan /api relatif dan bukannya URL penuh, dan tetapkan proksi pembangunan supaya /api dimajukan ke pelayan API. Kemudian buang sebarang tetapan CORS yang tidak diperlukan lagi.

Apa yang tidak perlu dilakukan

  • mode: "no-cors" dalam fetch. Ia tidak memintas apa-apa; ia memberi kod anda respons kosong yang tidak boleh dibaca.
  • Sambungan pelayar yang melumpuhkan CORS. Ia hanya menukar pelayar anda. Setiap pelawat masih melihat ralat itu.
  • Perkhidmatan “proksi CORS” awam untuk aplikasi sebenar. Mereka boleh membaca dan menukar semua yang melaluinya, dan ia sering tumbang.
  • Access-Control-Allow-Origin: * pada API yang menggunakan log masuk. Ia tidak berfungsi dengan kredensial juga, dan ia lalai yang salah untuk data persendirian.
  • Memantulkan sebarang header Origin kembali dengan kredensial dibenarkan. Itu membolehkan mana-mana laman web membuat permintaan log masuk bagi pihak pengguna anda. Gunakan senarai yang dibenarkan.

Punca biasa dalam aplikasi yang dibina AI

SituasiPembetulan
Bahagian hadapan memanggil API pihak ketiga dengan kunci rahsiaPindahkan panggilan ke bahagian belakang
Berfungsi dalam pratonton, gagal pada domain yang diterbitkanTambah asal yang diterbitkan dan domain tersuai ke senarai yang dibenarkan, atau gunakan laluan /api relatif
Ralat hanya pada POST, PUT atau DELETEPreflight tidak dikendalikan; tambah pengendalian OPTIONS dan header yang dibenarkan
Ralat muncul selepas menambah log masukKredensial memerlukan asal yang tepat dan Allow-Credentials
“Ralat CORS” tetapi tab Network menunjukkan 500Betulkan ralat pelayan dahulu
URL API dikod keras kepada localhostGunakan laluan relatif atau tetapan khusus persekitaran

CORS dalam Mythex

Apabila projek Mythex mempunyai laman web dan pelayan API, kedua-duanya berjalan sebagai perkhidmatan dalam projek yang sama, dan anda boleh bertukar antara mereka dalam pratonton. Meminta ejen supaya bahagian hadapan memanggil bahagian belakang melalui laluan /api relatif, diproksikan dalam pembangunan, mengelakkan kebanyakan masalah CORS. Jika anda memang memerlukan panggilan merentas asal, berikan ejen ralat tepat dari konsol dan asal yang terlibat. Semak hasilnya pada aplikasi yang diterbitkan juga, kerana alamatnya berbeza daripada pratonton. Lihat Aplikasi berbilang perkhidmatan dan Bahagian belakang API dalam dokumentasi, dan panduan kami tentang menyahpepijat aplikasi yang dibina AI dan bahagian hadapan berbanding bahagian belakang.

Senarai semak CORS

  • Baca ralat konsol penuh dan kod status permintaan yang gagal
  • Menolak 404 atau 500 yang tersembunyi
  • API yang menggunakan kunci rahsia dipanggil dari bahagian belakang, bukan pelayar
  • Pelayan menghantar Access-Control-Allow-Origin dengan asal yang tepat dibenarkan
  • Preflight OPTIONS dijawab dengan kaedah dan header yang dibenarkan, sebelum pengesahan
  • Header CORS hadir pada respons ralat
  • Kredensial: asal yang tepat, Allow-Credentials: true, dan tetapan kuki yang betul
  • Asal pratonton, diterbitkan dan domain tersuai semuanya diliputi, atau laluan /api relatif digunakan
  • Tiada no-cors, proksi awam, atau pintasan memantulkan sebarang asal

Soalan lazim

Apa maksud ralat CORS?

Halaman anda, yang dimuatkan dari satu asal, cuba membaca respons dari asal yang berbeza, dan pelayan itu tidak menyertakan header yang membenarkannya. Pelayar menyekat kod anda daripada membaca respons. Pembetulannya ada di pelayan, atau dalam cara permintaan dilalukan, bukan dalam kod bahagian hadapan.

Bolehkah saya membetulkan ralat CORS dari bahagian hadapan?

Tidak dengan betul. Tetapan seperti mode: 'no-cors' hanya menyembunyikan respons daripada kod anda. Anda membetulkannya dengan membuat pelayan menghantar header Access-Control-Allow-Origin yang betul, atau dengan memanggil API dari bahagian belakang anda sendiri atau proksi asal yang sama.

Adakah Access-Control-Allow-Origin: * selamat?

Ia sesuai untuk data awam yang sesiapa pun boleh baca, seperti API awam tanpa log masuk. Ia tidak boleh digunakan dengan kuki atau kredensial lain, dan untuk API persendirian anda sepatutnya menyenaraikan asal yang tepat yang dibenarkan.

Kenapa permintaan saya berfungsi dalam Postman atau curl tetapi tidak dalam pelayar?

CORS hanya dikuatkuasakan oleh pelayar. Alat seperti Postman dan curl tidak menggunakannya, jadi permintaan boleh berjaya di sana dan masih disekat apabila JavaScript halaman membuat permintaan itu.

Apa itu permintaan preflight?

Untuk permintaan yang tidak mudah, seperti POST JSON atau yang mempunyai header Authorization, pelayar mula-mula menghantar permintaan OPTIONS untuk bertanya pelayan kaedah dan header mana yang dibenarkan. Jika permintaan OPTIONS itu gagal atau tidak mempunyai header yang betul, permintaan sebenar tidak pernah dihantar.

Mythex · Pricing · Bina apa sahaja dengan AI · Templat laman web dan aplikasi · Mythex dibandingkan · Glosari pembinaan aplikasi AI · Alat percuma untuk membina aplikasi dengan AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)