P74 什么是跨域以及如何解决?
面试题:什么是跨域?浏览器为什么限制跨域?怎么解决?
1. 什么是跨域
浏览器同源策略(Same-Origin Policy):只有协议 + 域名 + 端口三者都相同才叫"同源"。任一不同就是跨域:
text
http://a.com:8080/api → http://b.com/api 跨域(域名不同)
http://a.com/api → https://a.com/api 跨域(协议不同)
http://a.com:8080/api → http://a.com:9090/api 跨域(端口不同)同源策略限制:跨域请求的响应不能被页面读取(Cookie、localStorage 也按源隔离),防止恶意网站窃取数据。
注意:跨域限制是浏览器的行为,服务端之间调用没有这个限制。
2. 常见解决方案
① CORS(跨域资源共享,最标准)
服务端返回响应头:
http
Access-Control-Allow-Origin: https://a.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true # 允许携带 CookieSpring 里:
java
@CrossOrigin(origins = "https://a.com")
// 或 WebMvcConfigurer 全局配置复杂请求(非简单请求)会先发 OPTIONS 预检,服务端要处理。
② Nginx 反向代理(最常用)
把跨域转成同源:前端只请求同域地址,Nginx 转发到后端:
nginx
location /api/ {
proxy_pass http://backend:8080/;
}前端访问 同域/api/xxx,浏览器眼里没有跨域。
③ JSONP(老方案,仅 GET)
利用 <script> 标签不受同源限制,动态加载回调函数;只支持 GET,已基本被 CORS 取代。
④ postMessage / 代理
iframe 跨域通信用 window.postMessage;开发环境用 Webpack devServer 代理。
3. 加分点
- 说出 CORS 预检(preflight)机制:非简单请求先 OPTIONS 确认;
- 提"Cookie 跨域要
withCredentials+Allow-Credentials,且不能*通配源"; - 网关/微服务统一解决:在网关层配 CORS,服务端不再各自处理;
- 追问"同源策略防什么":防 CSRF 数据读取、防恶意站点读你的登录态数据。
一句话总结
跨域是浏览器的同源策略限制(协议/域名/端口不同即跨域);解决:CORS 响应头(标准)、Nginx 反向代理(把跨域变同源,最常用)、JSONP(仅 GET)等;微服务在网关统一配 CORS。