Access to fetch at '...' from origin '...' has been blocked by CORS policyNo 'Access-Control-Allow-Origin' header is present on the requested resourceThe request works in curl and Postman but not in the browserEs tentador verlo como un problema de configuración: añades un origen y publicas la función. Pero piensa en lo que implica una llamada exitosa desde el navegador. La clave viaja en una cabecera que las herramientas de desarrollo del propio usuario muestran completa. Está en el bundle si la incrustaste, y en la pestaña de red si no. Cualquiera que abra la página la tiene.
Las claves filtradas así no son un riesgo teórico. Los buscadores de código público las encuentran continuamente, y una clave robada en una API de pago por token se convierte directamente en la factura de otra persona cargada a tu cuenta. Por eso la mayoría de los proveedores fijan un allow-origin restrictivo en lugar de *: no es un descuido, es una negativa deliberada.
El patrón proxy son tres o cuatro líneas de código de servidor: tu página llama a tu backend, tu backend guarda la clave y llama al proveedor. También te da el lugar donde poner límites de velocidad y de gasto por usuario, que de todos modos quieres.
Pregunta al endpoint qué orígenes permite realmente:
curl -s -I -X OPTIONS 'YOUR_BASE_URL/chat/completions' \
-H 'Origin: https://example.com' \
-H 'Access-Control-Request-Method: POST' \
| grep -i 'access-control'
Si Access-Control-Allow-Origin devuelve un dominio concreto en lugar de *, las llamadas desde el navegador en tu origen no van a funcionar, y ningún cambio en el lado del cliente lo va a cambiar.
/api/chat en tu propio dominio; ese gestor añade la cabecera Authorization y reenvía la petición. No hay CORS de por medio, porque el navegador solo habla con tu origen.NEXT_PUBLIC_, VITE_ y REACT_APP_ se compilan dentro del JavaScript que publicas. Una clave puesta ahí queda publicada, no configurada.https://apiclan.us como origen, a propósito: las claves deben vivir en un servidor. La configuración de base URL para clientes del lado del servidor está en el inicio rápido.Revisado por última vez el 2026-10-01. Escrito a partir de problemas diagnosticados en una pasarela compatible con OpenAI en producción, no recopilado de otras webs.