logo
GeekFormat

Inspector CORS

Painel de diagnóstico CORS

O servidor simula a solicitação preflight e a solicitação real para determinar rapidamente se o problema está em Allow-Origin, Allow-Headers ou credentials.

Simula en servidor solicitudes preflight CORS y solicitudes reales, verifica las 6 cabeceras de respuesta una por una, localiza con precisión errores de configuración cross-origin y proporciona código de corrección para múltiples frameworks como Nginx/Node.js/Spring.

Sugestões Relacionadas

Casos de uso

  • Cuando aparece el error No 'Access-Control-Allow-Origin' header en la consola del navegador, usa inmediatamente esta herramienta para verificar las cabeceras CORS que realmente devuelve la API objetivo
  • Durante la fase de integración frontend-backend en proyectos separados, verifica que la configuración CORS del backend funcione correctamente, evitando perder tiempo cambiando configuración a ciegas
  • Después de configurar proxy inverso Nginx, Apache o API Gateway (Kong/APISIX/Spring Cloud Gateway), verifica que las reglas CORS se transmitan correctamente
  • Cuando fallan solicitudes cross-origin que llevan Cookie, alterna el modo credentials para detectar conflictos de configuración entre Allow-Credentials y Allow-Origin
  • Después de añadir cabeceras personalizadas (como X-Token, X-Requested-With) la solicitud es bloqueada, verifica si están correctamente declaradas en Allow-Headers
  • Solicitudes con métodos no simples como PUT/DELETE/PATCH fallan en CORS, verifica si Allow-Methods incluye el método correspondiente
  • El frontend no puede leer cabeceras de respuesta personalizadas (como X-Request-Id, X-Total-Count), verifica la configuración de Access-Control-Expose-Headers
  • Después de acelerar con CDN, CORS funciona intermitentemente, verifica si Vary: Origin está configurado correctamente para evitar que CDN cachee respuestas incorrectas
  • Errores CORS ocasionales en producción, reproduce el escenario del problema y conserva el mensaje de respuesta completo para que el backend lo depure
  • Al aprender los principios de CORS, observa la función de cada cabecera de respuesta mediante solicitudes reales, profundizando la comprensión del mecanismo cross-origin

Recursos

  • Simulación real en servidor de solicitudes preflight y solicitudes reales, sin interferencias de caché del navegador ni extensiones, resultados más precisos
  • Muestra por separado la respuesta de preflight OPTIONS y la respuesta real GET/POST, distinguiendo claramente en qué etapa ocurre el problema
  • Verifica las 6 cabeceras CORS principales una por una: Access-Control-Allow-Origin, Allow-Methods, Allow-Headers, Allow-Credentials, Expose-Headers, Max-Age, cada cabecera marcada individualmente con estado de aprobación/advertencia/error
  • Detecta inteligentemente el conflicto clásico entre comodín * y modo credentials, alertando inmediatamente sobre esta trampa de configuración más común
  • Soporta origen de solicitud Origin personalizado, métodos HTTP (GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS) y cabeceras de solicitud personalizadas arbitrarias
  • Permite alternar el modo con o sin credenciales (Cookie/cabecera Authorization/certificados cliente TLS), simulando escenarios con withCredentials=true
  • Detecta automáticamente si la cabecera Vary: Origin está configurada correctamente, evitando que CDN/proxy inverso cacheen respuestas CORS incorrectas
  • Muestra estructuradamente la configuración de caché preflight Max-Age, evaluando el impacto de la frecuencia de solicitudes preflight en el rendimiento
  • Verifica la configuración de Access-Control-Expose-Headers, confirmando qué cabeceras de respuesta pueden ser leídas por JavaScript en el frontend
  • Proporciona recomendaciones de corrección línea por línea, incluyendo ejemplos de configuración para frameworks servidor principales como Nginx, Apache, Node.js/Express, Spring Boot, Python/Django/Flask
  • Registra completamente los mensajes originales de solicitud y respuesta, incluyendo código de estado, todas las cabeceras de respuesta, vista previa del cuerpo de respuesta, facilitando la depuración profunda
  • Identifica automáticamente las diferencias entre solicitudes simples y solicitudes que requieren preflight, explicando por qué tu solicitud dispara el preflight OPTIONS
  • Detecta problemas CORS en escenarios de redirección (si cambia el Origin después de redirecciones 301/302/307/308)
  • Soporta detección de escenarios de contenido mixto HTTPS/HTTP, alertando sobre problemas relacionados con CORS causados por contenido mixto

Como Usar

  1. En el campo de URL de destino, escribe la dirección completa de la API a verificar (soporta http/https, debe incluir la ruta)
  2. En el campo Origin de solicitud, escribe el origen real de tu página frontend (como https://example.com, importante incluir protocolo y puerto, sin ruta)
  3. Selecciona el método HTTP (GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS), por defecto GET
  4. En el área de cabeceras personalizadas, añade las cabeceras que necesites enviar, una por línea en formato X-Token: abc123. Content-Type con tipos no simples como application/json disparará automáticamente preflight
  5. Marca la opción "Con credenciales (credentials)" según tu escenario; si tu código frontend usa withCredentials=true o credentials: 'include' en fetch, debes marcarla
  6. Haz clic en el botón "Iniciar verificación", la herramienta enviará secuencialmente desde el servidor la solicitud preflight OPTIONS y la solicitud real (si el preflight pasa o no es necesario)
  7. Revisa el informe de análisis: primero mira el resultado de evaluación general, luego verifica el estado de cada cabecera CORS una por una, ajusta la configuración del servidor según las recomendaciones de corrección de los errores en rojo, vuelve a verificar después de corregir

Perguntas frequentes

¿Por qué con Postman/curl la API funciona bien, pero cuando accede el navegador reporta error cross-origin?

¡Este es el problema CORS más clásico! Porque Postman y curl no están sujetos en absoluto a la política del mismo origen del navegador — son clientes HTTP, no navegadores, no interceptan respuestas, y tampoco envían automáticamente solicitudes preflight OPTIONS. Los errores cross-origin son un mecanismo de seguridad exclusivo del navegador; solo el entorno de ejecución JavaScript del navegador realiza comprobaciones CORS. Que Postman pueda conectar solo demuestra que la API en sí puede devolver datos, no demuestra que la configuración CORS sea correcta. Necesitas usar el navegador, o esta herramienta (que simula el flujo CORS del navegador en el servidor) para verificar, y ahí descubrirás el problema.

¿El error CORS es problema del frontend o del backend? ¿Quién debe arreglarlo?

El 99% de los errores CORS son problemas de configuración del backend (o problemas de configuración en capa Nginx/gateway), el frontend puede hacer muy poco. El núcleo de CORS es que el servidor "autoriza" al navegador mediante cabeceras de respuesta para permitir el acceso cross-origin; el frontend solo puede configurar withCredentials, establecer cabeceras de solicitud, etc., no puede eludir las restricciones de seguridad del navegador. Los proxies del frontend de los que se habla en internet (proxy devServer, proxy inverso Nginx que proxifican frontend y API al mismo origen) esencialmente "engañan" al navegador haciéndole creer que es una solicitud mismo origen, no resuelven realmente el problema CORS; en producción si frontend y backend son diferentes orígenes el backend aún necesita configurar CORS correctamente.

¿Por qué mi solicitud GET no tiene cross-origin, pero en cuanto la cambio a POST/PUT aparece cross-origin?

Porque GET normalmente cumple las condiciones de solicitud simple, el navegador envía la solicitud directamente; mientras que POST si envías Content-Type: application/json (el 90% de las APIs POST son esto), ya no pertenece a solicitud simple, disparará preflight OPTIONS. La solicitud preflight requiere que el servidor devuelva las cabeceras CORS correctas; mucha gente solo configuró cabeceras CORS para GET/POST pero no manejó el método OPTIONS, o la respuesta OPTIONS no tiene cabeceras, por lo que reporta error. Los métodos PUT/DELETE/PATCH por sí mismos no son métodos simples, inevitablemente disparan preflight.

¿Cómo resolver cross-origin en entorno de desarrollo? ¿Y en producción?

En entorno de desarrollo hay varias soluciones: ① Proxy integrado en el framework (devServer.proxy de Vue CLI, server.proxy de Vite, proxy de Create React App): proxifica las solicitudes de API al mismo origen que el servidor de desarrollo del frontend, el navegador cree que es solicitud mismo origen sin cross-origin; ② Desactivar parámetros de seguridad del navegador (por ejemplo Chrome con parámetro de inicio --disable-web-security), solo para pruebas temporales locales, absolutamente no para navegación normal; ③ Configurar CORS en el backend permitiendo origen localhost (recomendado, comportamiento consistente con producción). En producción el backend debe configurar CORS correctamente: configurar lista blanca de orígenes permitidos, establecer correctamente Allow-Methods/Allow-Headers/Allow-Credentials, añadir Vary: Origin, o usar gateway/Nginx para manejar CORS de forma unificada.

¿Se puede configurar Access-Control-Allow-Origin con múltiples orígenes? ¿Cómo configurar múltiples dominios para permitir cross-origin?

No, la cabecera de respuesta Access-Control-Allow-Origin solo puede tener un valor, ya sea un origen específico (como https://a.com), o *. El navegador no acepta múltiples orígenes (por ejemplo escribir https://a.com,https://b.com es inválido, el navegador lo considerará no coincidente). La forma correcta de configuración multi-origen es: el servidor mantiene una lista blanca de orígenes permitidos, cada vez que recibe una solicitud lee el valor de Origin en la cabecera de solicitud, verifica si ese Origin está en la lista blanca, si es así establece Access-Control-Allow-Origin como ese valor de Origin específico, y devuelve al mismo tiempo la cabecera Vary: Origin; si no está, no devuelve cabeceras CORS o devuelve error. No intentes devolver múltiples cabeceras Allow-Origin o separar múltiples valores por coma, el navegador no los reconoce.

¿La solicitud preflight OPTIONS necesita devolver lógica de negocio? ¿Puede devolver directamente 204?

La solicitud preflight OPTIONS no necesita devolver ninguna lógica de negocio ni cuerpo de respuesta, solo necesita devolver las cabeceras de respuesta CORS correctas y código de estado 200/204 es suficiente. El navegador al recibir las cabeceras CORS correctas considera que el preflight pasó, no leerá el contenido del body de la respuesta OPTIONS. Así que la mejor práctica es: interceptar directamente solicitudes OPTIONS en la capa Nginx/gateway, devolver 204 No Content y las cabeceras CORS correctas, sin reenviar al servidor de aplicaciones backend; esto aligera la carga del backend y también evita errores 405 causados por rutas backend que no soportan OPTIONS. Pero asegúrate de que las cabeceras CORS de la respuesta OPTIONS sean consistentes con las cabeceras CORS de la solicitud real.

¿Por qué configuré withCredentials: true, pero Cookie no se lleva?

Las solicitudes cross-origin con Cookie requieren cumplir simultáneamente tres condiciones: ① XMLHttpRequest.withCredentials = true en el frontend o credentials: 'include' en fetch; ② Cabecera de respuesta backend Access-Control-Allow-Credentials: true; ③ Access-Control-Allow-Origin no puede ser *, debe ser origen específico. Las tres condiciones son indispensables. Además presta atención a los atributos de Cookie: la Cookie debe tener establecido SameSite=None; Secure (entorno HTTPS) para poder llevarse en solicitudes cross-origin; si la Cookie es SameSite=Lax o Strict, en solicitudes cross-origin no se llevará; el atributo Domain de la Cookie debe estar configurado correctamente; también presta atención al impacto de las políticas de Cookie de terceros (navegadores como Chrome tienen restricciones sobre Cookies de terceros).

¿Qué relación hay entre CORS y CSRF? ¿Configurar CORS causará vulnerabilidades CSRF?

CORS es relajar las restricciones de acceso cross-origin, CSRF es ataque de falsificación de solicitudes entre sitios, son conceptos diferentes. Configurar CORS correctamente no causa directamente vulnerabilidades CSRF — porque CORS solo permite que JS lea respuestas, mientras que CSRF es cuando un atacante induce al usuario a enviar solicitudes sin saberlo (como etiquetas img, envío automático de formularios), estas solicitudes incluso sin CORS se envían llevando Cookie. Defender CSRF requiere usar CSRF Token, SameSite Cookie, verificar Origin/Referer y otras soluciones, no se puede defender CSRF deshabilitando CORS. Pero si al configurar CORS estableces Allow-Origin como * y permites credenciales, sí amplificará el riesgo CSRF, por eso en escenarios con credenciales absolutamente no se puede usar *, debes restringir estrictamente la lista blanca de orígenes.

¿La descarga de archivos, redirecciones, carga de etiquetas img/script tienen problemas CORS?

La carga de recursos cross-origin con etiquetas <img>, <script>, <link> normales (imágenes CDN, scripts JS, CSS) por defecto no tiene problemas CORS; estos son "recursos incrustados" no "solicitudes AJAX", el navegador permite cargarlos pero JS no puede leer el contenido. Pero si quieres manipular imágenes cross-origin en Canvas, o cargar estos recursos con fetch/XHR y leer el contenido, entonces necesitas CORS, y al mismo tiempo debes añadir el atributo crossorigin en la etiqueta. La descarga de archivos cross-origin (clic en etiqueta a para descargar) por defecto tampoco necesita CORS. Las redirecciones afectan CORS: si la solicitud preflight OPTIONS devuelve redirección 3xx, el navegador la rechazará directamente (Preflight redirect is not allowed); si la redirección de la solicitud real es entre orígenes diferentes, cada salto necesita devolver cabeceras CORS correctamente.

¿Cómo configurar CORS correctamente en Nginx? ¿Dan un ejemplo de configuración funcional?

Puntos clave de configuración recomendada en Nginx: ① Usar directiva map para coincidir con lista blanca de Origins, estableciendo dinámicamente la variable $cors_origin; ② Las solicitudes OPTIONS devuelven directamente 204 sin reenviar al backend; ③ add_header recuerda añadir el parámetro always para asegurar que respuestas de error también lleven cabecera; ④ Añadir Vary: Origin; ⑤ Configurar correctamente Allow-Methods/Allow-Headers/Credentials. Puedes encontrar configuraciones de ejemplo en las recomendaciones de corrección de los resultados de detección de esta herramienta; proporcionamos fragmentos de configuración verificados para frameworks principales como Nginx, Apache, Node.js Express, Spring Boot, Python Flask/Django, Koa, Go Gin.

Después de configurar CORS, ¿cómo verificar si tiene efecto?

Pasos para verificar CORS: ① Primero usa la detección online de esta herramienta, introduce URL, Origin, método, cabeceras, opción de credenciales, mira si cada comprobación del preflight y la solicitud real pasan; ② Abre el panel Network de DevTools del navegador, marca Disable cache para deshabilitar caché (evitando interferencia de caché antiguo), dispara la solicitud cross-origin, verifica que las cabeceras de respuesta del preflight OPTIONS y la solicitud real sean correctas; ③ En Console mira si hay errores relacionados con CORS; ④ Prueba diferentes escenarios: solicitudes GET sin cabeceras personalizadas, solicitudes POST con application/json, métodos PUT/DELETE, con Cookie/sin Cookie, con cabeceras personalizadas; ⑤ Simula solicitud OPTIONS con curl: curl -i -X OPTIONS -H "Origin: https://yoursource.com" https://api.example.com/endpoint, verifica que las cabeceras de respuesta sean correctas.

¿Por qué la solicitud cross-origin reporta error en Chrome pero funciona normalmente en Safari/Firefox? ¿O al revés?

Diferentes navegadores tienen diferencias en los detalles de implementación de la especificación CORS: ① Safari tiene restricciones más estrictas sobre Max-Age del caché preflight (versiones antiguas solo 600 segundos), la política de Cookies (ITP anti-rastreo inteligente) también es más estricta, puede causar problemas de Cookie cross-origin; ② Chrome tiene comprobaciones más estrictas sobre comodines con credenciales, Allow-Headers/Allow-Methods tampoco permiten *, algunas versiones de Firefox pueden ser más laxas; ③ IE antiguo (IE11) usa XDomainRequest en lugar de XMLHttpRequest estándar, la implementación CORS tiene muchas trampas (por ejemplo no soporta cabeceras personalizadas, solo soporta GET/POST); ④ Diferentes navegadores tienen diferencias sutiles en el manejo de cabecera Vary, manejo de redirecciones, manejo de cabeceras de seguridad. La solución es configurar estrictamente según la especificación CORS, no depender del comportamiento compatible de un navegador específico.

¿Cuánto es apropiado establecer Access-Control-Max-Age? ¿Qué problemas hay si se establece demasiado largo o demasiado corto?

Se recomienda establecer entre 3600 (1 hora) y 86400 (24 horas). Establecer demasiado corto (como 60 segundos): el caché preflight expira rápidamente, enviando frecuentemente solicitudes OPTIONS, aumentando el tiempo de solicitud y la presión del servidor, el impacto es notable en entornos de red móvil débil. Establecer demasiado largo (como 31536000, es decir un año): si actualizas la configuración CORS (por ejemplo añadiendo métodos permitidos, cabeceras), el resultado preflight antiguo en caché del navegador del usuario puede tardar mucho en expirar, durante ese periodo aparecerán problemas de que la configuración no tiene efecto. Además Chrome y Firefox truncarán automáticamente los valores que superen 86400 segundos a 86400 segundos, por más que lo establezcas no sirve de nada. En entorno de desarrollo puedes establecer -1 para deshabilitar el caché preflight, facilitando la depuración.

¿Las conexiones WebSocket tienen problemas cross-origin? ¿CORS aplica a WebSocket?

WebSocket (ws:// y wss://) no están sujetos al mecanismo CORS HTTP, porque WebSocket es un protocolo independiente, no son solicitudes HTTP AJAX. Pero la fase de handshake de WebSocket es una solicitud HTTP; el servidor puede verificar la cabecera Origin para decidir si permite la conexión — esto es control de permisos a nivel de WebSocket, no es CORS estándar, pero el principio es similar. Si la conexión WebSocket es rechazada, necesitas verificar la configuración de verificación Origin del servidor WebSocket, no las cabeceras CORS HTTP. Librerías como Socket.IO pueden tener su propia forma de configuración cross-origin, similar a la configuración CORS estándar pero no exactamente igual. Además, otras APIs del navegador como HTTP/2 Server Push, WebRTC también tienen su propio control de permisos, no siguen completamente el CORS HTTP.

¿Los resultados de detección de esta herramienta son consistentes con el comportamiento del navegador? ¿Por qué con la herramienta la detección pasa pero el navegador sigue reportando error?

Esta herramienta en el servidor simula estrictamente según la especificación W3C CORS el flujo de preflight y solicitud real del navegador, la lógica de comprobación de cabeceras CORS es básicamente consistente con los navegadores modernos. Si la herramienta detecta que pasa pero el navegador sigue reportando error, las posibles causas son: ① El navegador cacheó resultados preflight o respuestas antiguas, haz recarga forzada Ctrl+F5 o borra caché y vuelve a intentar; ② Extensiones del navegador (bloqueo de publicidad, protección de privacidad, plugins de seguridad) modificaron o interceptaron la solicitud; ③ El Origin, cabeceras de solicitud, método, opción de credenciales que escribiste en la herramienta no son consistentes con los que realmente envía el frontend (por ejemplo el frontend realmente lleva alguna cabecera personalizada que no añadiste en la herramienta); ④ Caché inconsistente en nodos CDN/proxy, el nodo al que la herramienta solicita y el nodo al que el navegador solicita devuelven resultados diferentes; ⑤ El navegador tiene políticas de seguridad especiales (como solicitudes a contenido mixto HTTP en páginas HTTPS son bloqueadas, restricciones especiales del protocolo file:// de archivos locales).

术语表

CORS (Cross-Origin Resource Sharing)
Compartición de Recursos de Origen Cruzado, estándar W3C, que permite al servidor declarar qué orígenes pueden acceder a recursos mediante nuevos campos de cabecera HTTP, es la solución oficial de los navegadores modernos para resolver problemas cross-origin.
Política del Mismo Origen (Same-Origin Policy)
Mecanismo de seguridad central del navegador; solo cuando protocolo, dominio y puerto son exactamente iguales se considera mismo origen, y JavaScript de orígenes diferentes por defecto no puede leer los recursos del otro.
Solicitud Preflight (Preflight Request)
Solicitud con método OPTIONS que el navegador envía automáticamente primero para solicitudes cross-origin no simples, usada para preguntar al servidor si permite la solicitud real posterior; solo después de pasar el preflight se envía la solicitud verdadera.
Solicitud Simple (Simple Request)
Solicitud cross-origin que cumple condiciones específicas (método GET/HEAD/POST, solo cabeceras seguras, Content-Type específico), que no necesita enviar preflight y envía la solicitud real directamente.
Access-Control-Allow-Origin (ACAO)
Cabecera de respuesta CORS principal, especifica el origen permitido para acceder al recurso, puede ser un URI de origen específico o comodín *, con credenciales no se puede usar *.
Access-Control-Allow-Methods (ACAM)
Cabecera de respuesta preflight, lista todos los métodos HTTP soportados por el servidor, múltiples métodos separados por coma.
Access-Control-Allow-Headers (ACAH)
Cabecera de respuesta preflight, lista todos los campos de cabecera de solicitud permitidos por el servidor; las cabeceras personalizadas enviadas por el frontend deben declararse aquí.
Access-Control-Allow-Credentials (ACAC)
Cabecera de respuesta, valor booleano true indica que se permite llevar credenciales como Cookie y Authorization en solicitudes cross-origin; en este caso Allow-Origin no puede ser *.
Access-Control-Max-Age (ACMA)
Cabecera de respuesta preflight, especifica el tiempo de caché del resultado preflight en segundos; una configuración razonable puede reducir solicitudes OPTIONS mejorando el rendimiento.
Vary: Origin
Cabecera de respuesta, le dice a CDN/proxy que el contenido de la respuesta varía según la cabecera Origin, al cachear debe incluir Origin como clave de caché para evitar desorden de caché de respuestas cross-origin.
Cabeceras de solicitud de lista segura CORS (CORS-safelisted request headers)
Cabeceras de solicitud que se pueden enviar sin necesidad de declararlas en Allow-Headers, incluyendo Accept, Accept-Language, Content-Language, Content-Type (valores específicos), etc.
Nombres de cabecera prohibidos (Forbidden header name)
Cabeceras de solicitud que el navegador prohíbe a JavaScript establecer mediante programación, como Host, Connection, Cookie, Origin, etc.; estas cabeceras son controladas automáticamente por el navegador.
Solicitud con credenciales (Credentialed Request)
Solicitud cross-origin que lleva credenciales de identidad como Cookie, información de autenticación HTTP, certificados cliente TLS; requiere que frontend y backend configuren conjuntamente withCredentials y Allow-Credentials.
Access-Control-Expose-Headers
Cabecera de respuesta, lista las cabeceras de respuesta a las que JavaScript puede acceder; por defecto solo unas pocas cabeceras básicas son accesibles, las cabeceras personalizadas deben declararse aquí.
Método OPTIONS
Uno de los métodos HTTP, usado para obtener las opciones de comunicación soportadas por el servidor; CORS lo usa para enviar solicitudes preflight, preguntando al servidor los métodos, cabeceras, credenciales permitidos.
Cabecera de solicitud Origin
Cabecera de solicitud añadida automáticamente por el navegador, indica de qué origen proviene la solicitud actual (protocolo+dominio+puerto); el servidor determina si permite cross-origin según esta cabecera.
Atributo crossorigin
Atributo de elementos HTML (como script, img, link), usado para especificar si se habilita la carga de recursos con CORS; los valores son anonymous (sin credenciales) y use-credentials (con credenciales).
Modo de solicitud no-cors
Un mode de la API fetch, que permite enviar solicitudes cross-origin pero solo puede enviar solicitudes simples y JavaScript no puede leer el contenido de la respuesta, equivalente a enviar una solicitud opaca (Opaque Response).

Tabla de comparación completa de cabeceras de respuesta CORS

Tabla de判定 de qué solicitudes disparan preflight

Tabla de referencia rápida de errores CORS comunes y soluciones

Troubleshooting