<p>JavaScript 本身不处理 CORS,前端只需正常发起 fetch/XHR 请求;关键在后端配置 Access-Control-Allow-* 响应头,区分简单请求与预检请求(OPTIONS),并正确响应,浏览器才放行响应。</p>

JavaScript 本身不处理跨域资源共享(CORS)问题,也不需要“绕过”或“解决”它——浏览器自动执行同源策略并检查响应头,前端只需按标准方式发请求即可。真正起作用的是后端是否返回合法的 Access-Control-Allow-* 响应头。
核心逻辑:浏览器拦截响应,而非阻止请求
当页面从 http://localhost:5173 向 https://api.example.com 发起 fetch 请求时:
- 浏览器会自动在请求头中添加
Origin: http://localhost:5173 - 请求实际发出去了,服务器也正常返回了数据
- 但浏览器收到响应后,检查有没有
Access-Control-Allow-Origin头 - 如果没有,或值不匹配,就拒绝把响应交给 JavaScript,控制台报错
区分简单请求和预检请求(OPTIONS)
是否触发预检,取决于你写的请求是否“复杂”:
-
简单请求:方法是 GET/HEAD/POST,且
Content-Type是text/plain、application/x-www-form-urlencoded或multipart/form-data,且没带自定义 header(如Authorization) -
非简单请求:用 PUT/DELETE/PATCH、发送 JSON(
Content-Type: application/json)、加了Authorization或X-Token等自定义头 → 浏览器会先发一个 OPTIONS 请求
后端必须对 OPTIONS 请求返回 204 或 200,并带上完整 CORS 头,主请求才会发出。
立即学习“Java免费学习笔记(深入)”;
后端必须配置的关键响应头
这些头由服务端设置,前端无法伪造。常见组合包括:
-
Access-Control-Allow-Origin:开发可设为http://localhost:5173;生产环境避免用*,尤其当涉及凭证时 -
Access-Control-Allow-Methods:明确列出允许的方法,如GET, POST, PUT, DELETE,不能只写* -
Access-Control-Allow-Headers:列出前端实际发送的额外头,如Content-Type, Authorization, X-Request-ID -
Access-Control-Allow-Credentials:设为true才能传 Cookie 或 token;此时Access-Control-Allow-Origin必须指定具体域名,不可为* -
Access-Control-Expose-Headers(可选):若前端需读取响应里的自定义 header(如X-Rate-Limit),必须在这里显式声明
开发阶段可用的代理方案
本地调试时,可通过构建工具代理请求,让前后端看起来“同源”,从而避开浏览器 CORS 检查:
- Vite 中配置
vite.config.js:
- 前端仍调用
fetch('/api/users'),开发服务器自动转发到后端,不触发跨域 - 注意:这只是开发便利手段,上线必须靠后端正确配 CORS


















