跨域本质是浏览器同源策略的限制,非后端问题;浏览器因安全强制拦截响应,只允许协议、域名、端口三者完全相同时通信;解决需后端配置CORS响应头(如Access-Control-Allow-Origin),并区分简单请求与预检请求处理。

跨域问题本质是浏览器同源策略的限制,不是请求发不出去,而是浏览器拦截了响应结果。回答时紧扣“谁控制、为什么、怎么配”三个层次,避免只背术语。
先说清楚什么是跨域和为什么存在
同源指协议、域名、端口三者完全相同。只要有一个不同,就算跨域。比如 http://a.com 请求 https://a.com(协议不同)或 http://a.com:8080 请求 http://a.com:8081(端口不同),都会被拦截。
这个机制是浏览器强制执行的安全策略,目的是防止恶意网站读取用户在其他网站的敏感数据(如 Cookie、本地存储)。注意:跨域限制只作用于浏览器端,用 curl、Postman 或服务端发请求都不受限制。
CORS 是什么?关键在后端配置
CORS 全称 Cross-Origin Resource Sharing,是 W3C 标准,核心是后端在响应头里加字段,告诉浏览器“允许谁来访问我”。前端不能“开启 CORS”,只能配合(比如带凭证时设 credentials: 'include')。
重点响应头包括:
-
Access-Control-Allow-Origin:必须明确指定域名(如
https://myapp.com),不能写*同时又要求携带 Cookie; -
Access-Control-Allow-Methods:列出允许的请求方法,如
GET, POST, PUT; -
Access-Control-Allow-Headers:前端自定义请求头(如
Authorization)必须在这里声明; -
Access-Control-Allow-Credentials: true:表示允许传 Cookie,此时 Origin 不能为
*; - Access-Control-Max-Age:缓存预检结果,减少重复 OPTIONS 请求。
区分简单请求和预检请求(面试高频陷阱)
浏览器对请求自动分类:
-
简单请求:满足 GET/HEAD/POST + Content-Type 是
text/plain、application/x-www-form-urlencoded或multipart/form-data。这类请求直接发,后端只需返回对应 CORS 头即可; -
非简单请求:比如用
PUT、DELETE,或带Content-Type: application/json、或加了Authorization头。浏览器会先发一个 OPTIONS 预检请求,确认服务器是否允许,再发真实请求。
面试常问:“为什么我加了 CORS 头还是报错?”——大概率是后端没处理 OPTIONS 请求,或预检响应头漏了 Access-Control-Allow-Headers 等字段。
开发 vs 生产环境的解法要分开说
面试官爱考落地细节,不能只说“用 CORS”:
-
开发阶段:用 Webpack/Vite 的 proxy 功能做反向代理(如把
/api代理到http://localhost:3000),让请求看起来是同源的; - 生产阶段:Nginx 反向代理更稳妥(前端静态资源和 API 同域),或者由后端统一配置 CORS(推荐,职责清晰);
- 补充说明:JSONP 已淘汰(只支持 GET、无错误捕获)、postMessage 适用于 iframe 场景、WebSocket 本身不受同源限制——这些可提,但强调它们是特定场景的补充,不是通用方案。











