Guies

Com arreglar errors CORS (i per què passen)

Un error CORS vol dir que la teva pàgina web ha intentat llegir una resposta d’un origen diferent (un altre domini, port o protocol), i aquest servidor no ha enviat les capçaleres que diuen que és permès. Els navegadors bloquegen la resposta per protegir els usuaris. Ho arregles al servidor, retornant una capçalera Access-Control-Allow-Origin per a l’origen del teu lloc i gestionant les peticions preflight OPTIONS, o ho evites enviant la petició a través del teu propi backend al mateix origen.

És un dels errors més confusos del desenvolupament web, perquè la petició sovint arriba bé al servidor. Aquesta guia explica què està passant i com arreglar cada variant.

Què vol dir «origen»

Un origen és la combinació de protocol, domini i port:

URLOrigen
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (subdomini diferent, per tant origen diferent)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (port diferent, per tant origen diferent)

Els navegadors segueixen la política del mateix origen: el JavaScript d’una pàgina pot llegir lliurement les respostes del seu propi origen, però no les d’altres. CORS (Cross-Origin Resource Sharing) és el sistema que permet que un servidor hi doni el seu consentiment: «les respostes meves poden ser llegides per pàgines d’aquests orígens».

Dues conseqüències sorprenen la gent:

  • La petició sovint arriba al servidor. CORS normalment bloqueja que el teu codi llegeixi la resposta, no que el servidor rebi la petició. Un POST pot haver-se desat encara que vegis un error.
  • Només els navegadors l’apliquen. curl, Postman i el codi del servidor ignoren CORS per complet. Per això, «funciona a Postman» no et diu res sobre CORS.

Pas 1: llegeix l’error exacte

Obre les eines de desenvolupador (clic dret → Inspecciona), ves a la Consola i llegeix el missatge complet. La redacció de Chrome t’indica quin problema tens:

El missatge contéQuè està malament
No 'Access-Control-Allow-Origin' header is presentEl servidor no ha enviat la capçalera, o la petició ha fallat abans d’arribar al teu codi CORS (per exemple un 404 o un 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originEl servidor permet un origen diferent del teu
Response to preflight request doesn't pass access control checkLa petició preflight OPTIONS ha fallat
...must not be the wildcard '*' when the request's credentials mode is 'include'Estàs enviant cookies, i el servidor ha respost amb *
Request header field authorization is not allowedEl servidor no ha inclòs aquella capçalera a Access-Control-Allow-Headers

Despréns, obre la pestanya Xarxa, troba la petició que falla (i qualsevol petició OPTIONS prèvia) i mira el seu codi d’estat i les capçaleres de resposta.

Mira primer el codi d’estat. Molts «errors CORS» són en realitat un error del servidor disfressat. Si el servidor falla o retorna un 404, la seva resposta d’error sovint no té capçaleres CORS, així que el navegador informa de CORS en lloc del problema real. Arregla el 500 o el 404, i és possible que l’error CORS desaparegui.

Pas 2: decideix si hauries de cridar aquesta API des del navegador

Abans d’afegir capçaleres, pregunta’t: ha de cridar el navegador aquesta API directament?

  • Una API de tercers que necessita una clau secreta (OpenAI, la clau secreta de Stripe, la majoria de serveis de correu) mai no s’ha de cridar des del navegador. La clau seria visible per a tots els visitants. Crida-la des del teu backend, i el problema de CORS desapareix, perquè les peticions servidor a servidor no estan subjectes a CORS. Consulta com mantenir segures les claus d’API.
  • Una API de tercers que no controles i que no envia capçaleres CORS no es pot arreglar des del teu costat. Crida-la des del teu backend.
  • La teva pròpia API es pot arreglar configurant-la bé. Continua més avall.

Pas 3: arregla-ho al teu servidor

El servidor ha d’afegir les capçaleres correctes a les seves respostes, incloses les respostes d’error.

Per a la petició real, envia:

  • Access-Control-Allow-Origin: https://myapp.com (l’origen exacte del teu front end, sense barra final)
  • Vary: Origin, si el valor depèn de quin origen ha fet la petició

Per a la petició preflight OPTIONS, respon amb un estat d’èxit (200 o 204) i:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (cada capçalera personalitzada que enviïs)
  • Opcionalment Access-Control-Max-Age: 600, perquè el navegador guardi el preflight una estona

La majoria de frameworks tenen un paquet o una opció que fa això. A Express, el paquet cors; a FastAPI, CORSMiddleware; a ASP.NET Core, AddCors; a Spring, @CrossOrigin o una configuració de CORS. Una configuració típica d’Express:

import cors from "cors";

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

Posa la gestió de CORS abans de les teves rutes i de l’autenticació, perquè les peticions preflight (que no porten inici de sessió) no siguin rebutjades amb un 401.

Amb un constructor d’IA, descriu la configuració amb precisió:

El front end a https://myapp.com crida l’API a https://api.myapp.com i rep «Response to preflight request doesn't pass access control check». Configura CORS a l’API perquè només permeti exactament https://myapp.com i l’origen de la vista prèvia, permet GET, POST, PATCH, DELETE amb les capçaleres Content-Type i Authorization, gestiona OPTIONS abans de l’autenticació i inclou també les capçaleres CORS a les respostes d’error.

Pas 4: gestiona les cookies i les credencials

Si el teu front end envia cookies (per exemple, una sessió d’inici de sessió) a un altre origen, els dos costats han d’estar d’acord:

  • El front end defineix credentials: "include" a fetch, o withCredentials: true a axios.
  • El servidor envia Access-Control-Allow-Credentials: true.
  • La Access-Control-Allow-Origin del servidor ha de ser l’origen exacte, no *.

Les cookies entre llocs diferents també necessiten SameSite=None; Secure a la cookie, i alguns navegadors restringeixen més les cookies de tercers. És una raó més per preferir l’enfocament del pas 5.

Pas 5: evita CORS amb una configuració del mateix origen

Sovint la solució més neta és no fer peticions entre orígens. Serveix l’API des del mateix origen que la pàgina, per exemple a https://myapp.com/api/...:

  • En desenvolupament, la majoria de servidors de desenvolupament poden fer de proxy. La configuració server.proxy de Vite pot reenviar /api al teu backend en un altre port, de manera que el navegador només parla amb un sol origen.
  • En producció, encamina /api al backend mitjançant les regles de rewrite o de proxy del teu allotjament, o serveix el front end i l’API des d’un mateix servidor.

El front end llavors crida una ruta relativa com fetch("/api/orders"). No hi ha cap petició entre orígens, cap preflight entre orígens i cap mal de cap amb les cookies. A més, no cal codificar un domini d’API que canvia entre la vista prèvia i la producció.

Canvia el front end perquè cridi el backend amb rutes relatives /api en lloc d’una URL completa, i configura un proxy de desenvolupament perquè /api reenviï al servidor de l’API. Després elimina les configuracions de CORS que ja no necessitem.

Què no has de fer

  • mode: "no-cors" a fetch. No salta res; només dona al teu codi una resposta buida i il·legible.
  • Extensions del navegador que desactiven CORS. Només canvien el teu navegador. Tots els visitants continuen veient l’error.
  • Serveis públics de «proxy CORS» per a apps reals. Poden llegir i modificar tot el que hi passa, i es cauen.
  • Access-Control-Allow-Origin: * en una API que fa servir inicis de sessió. Tampoc no funciona amb credencials, i és el valor per defecte equivocat per a dades privades.
  • Reflectir qualsevol capçalera Origin de tornada amb credencials permeses. Això permet que qualsevol web faci peticions amb sessió iniciada en nom dels teus usuaris. Fes servir una llista blanca.

Causes habituals a les apps construïdes amb IA

SituacióArranjament
El front end crida una API de tercers amb una clau secretaMou la crida al backend
Funciona a la vista prèvia, falla al domini publicatAfegeix a la llista permesa els orígens publicat i de domini personalitzat, o fes servir rutes relatives /api
L’error només apareix en POST, PUT o DELETEPreflight no gestionat; afegeix la gestió de OPTIONS i les capçaleres permeses
L’error ha aparegut després d’afegir l’inici de sessióLes credencials necessiten un origen exacte i Allow-Credentials
«Error CORS» però la pestanya Xarxa mostra un 500Arregla primer l’error del servidor
URL de l’API codificada com a localhostFes servir rutes relatives o una configuració per entorn

CORS a Mythex

Quan un projecte de Mythex té un lloc web i un servidor d’API, tots dos s’executen com a serveis del mateix projecte, i pots canviar entre ells a la vista prèvia. Demanar a l’agent que el front end cridi el backend mitjançant una ruta relativa /api, amb proxy en desenvolupament, evita la majoria de problemes de CORS. Si de veritat necessites crides entre orígens, dona a l’agent l’error exacte de la consola i els orígens implicats. Comprova el resultat també a l’app publicada, ja que la seva adreça és diferent de la de la vista prèvia. Consulta Apps multiservei i Backends d’API a la documentació, i les nostres guies sobre com depurar una app construïda amb IA i front end vs back end.

Llista de verificació de CORS

  • S’ha llegit el missatge complet de la consola i el codi d’estat de la petició que falla
  • S’ha descartat un 404 o un 500 amagat
  • Les APIs amb clau secreta es criden des del backend, no des del navegador
  • El servidor envia Access-Control-Allow-Origin amb els orígens permesos exactes
  • La petició preflight OPTIONS es respon amb els mètodes i capçaleres permesos, abans de l’autenticació
  • Les capçaleres CORS són presents a les respostes d’error
  • Credencials: origen exacte, Allow-Credentials: true i configuració de cookies correcta
  • Orígens de vista prèvia, publicat i de domini personalitzat coberts, o rutes relatives /api utilitzades
  • Cap drecera de no-cors, de proxies públics ni de reflectir qualsevol origen

Preguntes

Què vol dir un error CORS?

La teva pàgina, carregada des d’un origen, ha intentat llegir una resposta d’un origen diferent, i el servidor d’aquest origen no ha inclòs les capçaleres que ho permeten. El navegador impedeix que el teu codi llegeixi la resposta. L’arranjament és al servidor, o en com s’encamina la petició, no al codi del front end.

Puc arreglar un error CORS des del front end?

No de manera adequada. Opcions com mode: 'no-cors' només amaguen la resposta al teu codi. L’arranjament és fer que el servidor enviï la capçalera Access-Control-Allow-Origin correcta, o cridar l’API des del teu propi backend o des d’un proxy del mateix origen.

És segur Access-Control-Allow-Origin: *?

És correcte per a dades públiques que qualsevol pot llegir, com una API pública sense inici de sessió. No es pot fer servir amb cookies ni altres credencials, i per a APIs privades has de llistar els orígens exactes permesos.

Per què la meva petició funciona a Postman o curl però no al navegador?

CORS només l’apliquen els navegadors. Eines com Postman i curl no el fan complir, així que una petició pot funcionar allà i encara ser bloquejada quan la fa el JavaScript de la pàgina.

Què és una petició preflight?

Per a peticions que no són simples, com un POST amb JSON o una que porta una capçalera Authorization, el navegador primer envia una petició OPTIONS per preguntar al servidor quins mètodes i capçaleres estan permesos. Si aquesta petició OPTIONS falla o no té les capçaleres correctes, la petició real mai no s’envia.

Mythex · Pricing · Crea qualsevol cosa amb IA · Plantilles de llocs web i aplicacions · Mythex comparat · Glossari de creació d’aplicacions amb IA · Eines gratuïtes per crear aplicacions amb IA · English

English አማርኛ العربية Български বাংলা Bosanski Č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 Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ 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 简体中文 繁體中文(香港) 繁體中文(台灣)