文章目录前言一、同源策略浏览器的安全门卫1.1 什么是同源先搞懂三兄弟1.2 浏览器为啥要搞同源策略安全第一二、跨域本质浏览器拦的不是服务器三、2026年主流跨域解决方案全场景覆盖3.1 CORS现代Web跨域标准之王最推荐3.1.1 什么是CORS3.1.2 CORS工作流程极简版3.1.3 简单请求 vs 预检请求OPTIONS3.1.4 核心响应头必须掌握3.1.5 实战代码Express前端3.2 代理服务器开发/生产万能钥匙3.2.1 原理最容易理解3.2.2 开发环境Vite/Webpack代理神器3.2.3 生产环境Nginx反向代理大厂标准3.3 JSONP兼容老浏览器的上古方案了解即可3.3.1 原理3.3.2 实战代码3.4 postMessageiframe/跨窗口通信专用方案3.4.1 适用场景3.4.2 实战代码3.5 其他方案了解3.5.1 document.domain主域相同子域跨域3.5.2 WebSocket实时通信无跨域3.5.3 window.name/location.hash过时方案四、方案选型指南2026年最佳实践4.1 开发环境本地调试4.2 生产环境自有服务、前后端分离4.3 iframe/多窗口跨域通信4.4 调用第三方接口不可控4.5 绝对禁忌生产环境五、常见跨域坑与避坑指南2026最新5.1 带Cookie跨域失败最常见5.2 自定义请求头触发OPTIONS预检5.3 端口号被忽略本地开发5.4 Nginx代理后Cookie丢失5.5 浏览器缓存导致跨域异常六、总结跨域其实很简单P.S. 目前国内还是很缺AI人才的希望更多人能真正加入到AI行业共同促进行业进步增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow教程通俗易懂高中生都能看懂还有各种段子风趣幽默从深度学习基础原理到各领域实战应用都有讲解我22年的AI积累全在里面了。注意教程仅限真正想入门AI的朋友否则看看零散的博文就够了。前言老铁们做前端开发的谁没被跨域坑过我敢说只要你写过AJAX、调过接口、玩过前后端分离跨域这两个字绝对是你开发路上的“拦路虎”。控制台那一句经典的No Access-Control-Allow-Origin header is present on the requested resource能让多少刚入行的小伙伴直接破防怀疑人生。我干开发22年从早年的ASP、PHP混写到后来的jQuery时代再到现在的Vue、React三大框架横行跨域问题就像狗皮膏药一样一直跟着Web开发。很多人知其然不知其所以然只知道CORS、JSONP、Nginx代理这些名词却不懂浏览器为啥要搞出同源策略各种方案的本质区别是什么生产环境该怎么选才最稳妥、最安全。今天这篇文章我就用最通俗、最接地气的话把同源策略的来龙去脉、跨域的本质、以及2026年最新、最实用的解决方案一次性给你讲透。保证你看完不仅能解决日常开发的跨域坑面试的时候也能吹得面试官一愣一愣的直接拿捏。一、同源策略浏览器的安全门卫1.1 什么是同源先搞懂三兄弟要懂跨域先懂同源。同源Same-Origin是浏览器安全的基石判断两个URL是否同源只看三个东西协议、域名、端口。三者必须完全一致差一个字母、一个符号、一个数字都算跨域。我给你举几个例子一看就懂当前页面https://www.baidu.com/index.htmlhttps://www.baidu.com/api/user✅ 同源协议、域名、端口全一样http://www.baidu.com/api/user❌ 不同源协议不同https vs httphttps://map.baidu.com/api❌ 不同源子域名不同www vs maphttps://www.baidu.com:8080/api❌ 不同源端口不同默认443 vs 8080https://baidu.com/api❌ 不同源域名不同www.baidu.com vs baidu.com简单记协议、域名、端口一个都不能少。少一个、变一个浏览器就不认你是自己人。1.2 浏览器为啥要搞同源策略安全第一很多新手吐槽同源策略太烦了限制这限制那直接关掉不香吗大错特错同源策略是浏览器的安全门卫没有它你上网就等于裸奔。我给你打个比方你登录了银行网站bank.comCookie里存了登录态。这时候你不小心点开一个恶意网站hacker.com。如果没有同源策略恶意网站的JS就能直接读取你银行网站的Cookie、获取你的账户信息、甚至偷偷发起转账请求——你的钱瞬间就没了。同源策略的核心目的就是隔离不同源的资源防止恶意网站窃取数据、伪造请求、篡改DOM。它主要限制三件事AJAX/Fetch请求限制不同源的接口直接请求会被浏览器拦截控制台报错DOM访问限制不同源的iframe/窗口不能互相读取DOM、调用方法存储访问限制不同源不能读取对方的Cookie、LocalStorage、IndexedDB一句话总结同源策略是浏览器的安全底线跨域问题是安全与开发便利的矛盾产物。我们要做的不是打破安全而是在安全框架内找到合法合规的通行证。二、跨域本质浏览器拦的不是服务器这里有个超级关键的点90%的新手都搞混跨域拦截是浏览器干的跟服务器没关系我再强调一遍服务器收到跨域请求正常处理、正常返回数据浏览器拿到服务器返回的结果检查是否符合同源策略不符合浏览器直接把数据扔掉抛给你一个跨域错误服务器全程不知道自己的响应被浏览器丢了这就好比你浏览器去快递站服务器取快递数据。快递站不管你是谁把包裹给你了。但你回家路上被小区保安同源策略拦住了“这个包裹不是你家同源的不能带进小区” 于是你只能把包裹扔了还跟主人前端代码说“取不到被拦了”所以服务器没毛病响应正常问题出在浏览器的安全校验解决跨域本质就是让浏览器知道这个跨域请求是合法的、被允许的三、2026年主流跨域解决方案全场景覆盖3.1 CORS现代Web跨域标准之王最推荐3.1.1 什么是CORSCORSCross-Origin Resource Sharing跨域资源共享是W3C官方标准2026年开发首选、最规范、最安全的跨域方案。原理一句话服务器通过HTTP响应头告诉浏览器“这个来源我允许访问放行”3.1.2 CORS工作流程极简版浏览器发起跨域请求自动在请求头加Origin: 当前域名服务器收到请求检查Origin是否在白名单允许返回Access-Control-Allow-Origin: 允许的域名浏览器检查响应头匹配成功把数据给前端不允许浏览器拦截抛跨域错误3.1.3 简单请求 vs 预检请求OPTIONSCORS分两种请求面试必考① 简单请求满足两个条件方法GET/HEAD/POST请求头只有Accept、Accept-Language、Content-Language、Content-Type仅限application/x-www-form-urlencoded、multipart/form-data、text/plain特点直接发请求服务器返回CORS头即可。② 非简单请求PUT/DELETE/自定义头/Content-Type:application/json特点浏览器先发OPTIONS预检请求问服务器“我要发XX方法、带XX头你允许吗”服务器同意返回204浏览器再发真实请求服务器拒绝直接拦截真实请求不发3.1.4 核心响应头必须掌握# 允许的源生产别用*要指定具体域名 Access-Control-Allow-Origin: https://www.your-frontend.com # 允许的请求方法 Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS # 允许的请求头 Access-Control-Allow-Headers: Content-Type,Authorization,Token # 是否允许携带Cookietrue时Allow-Origin不能用* Access-Control-Allow-Credentials: true # 预检缓存时间秒减少OPTIONS请求 Access-Control-Max-Age: 864003.1.5 实战代码Express前端后端Express// 全局CORS中间件生产建议用cors库app.use((req,res,next){// 允许的前端域名constallowOrigin[https://www.a.com,https://www.b.com]constoriginreq.headers.originif(allowOrigin.includes(origin)){res.header(Access-Control-Allow-Origin,origin)}res.header(Access-Control-Allow-Methods,GET,POST,PUT,DELETE,OPTIONS)res.header(Access-Control-Allow-Headers,Content-Type,Authorization)res.header(Access-Control-Allow-Credentials,true)// 处理OPTIONS预检if(req.methodOPTIONS){returnres.sendStatus(204)}next()})前端带Cookie请求// fetchfetch(https://api.your-backend.com/user,{method:GET,credentials:include// 关键携带Cookie})// axiosaxios.get(https://api.your-backend.com/user,{withCredentials:true// 关键})优点标准、支持所有请求、安全、可控缺点必须后端配合配置适用前后端分离、自有服务、生产环境首选3.2 代理服务器开发/生产万能钥匙3.2.1 原理最容易理解同源策略只限制浏览器服务器之间通信没有跨域。代理方案前端 → 请求同源代理地址如/api/xxx代理服务器本地/Vite/Nginx→ 转发到真实后端代理服务器拿到响应 → 返回给前端浏览器以为是同源请求直接放行3.2.2 开发环境Vite/Webpack代理神器Vite配置2026最主流// vite.config.jsexportdefault{server:{proxy:{/api:{target:https://api.your-backend.com,// 真实后端changeOrigin:true,// 改Host头rewrite:(path)path.replace(/^\/api/,)// 路径重写可选}}}}前端直接请求/api/user浏览器不跨域开发爽到爆。3.2.3 生产环境Nginx反向代理大厂标准线上项目几乎都用Nginx统一入口彻底消灭跨域。Nginx配置server { listen 80; server_name www.your-site.com; # 前端静态文件 location / { root /usr/share/nginx/html; index index.html; } # 接口代理到后端 location /api { proxy_pass https://api.your-backend.com; # 真实后端 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }用户访问www.your-site.com/api/userNginx转发到后端浏览器全程以为是同源。优点前端无感知、彻底解决跨域、安全、可加限流/负载均衡缺点需配置代理服务器适用开发环境调试、生产环境统一入口3.3 JSONP兼容老浏览器的上古方案了解即可3.3.1 原理利用script标签不受同源策略限制的特性前端动态创建script srchttps://api.com?callbackhandleData服务器返回handleData({ name:张三 })JS函数调用浏览器加载执行前端拿到数据3.3.2 实战代码// 前端functionhandleData(data){console.log(拿到数据:,data)}constscriptdocument.createElement(script)script.srchttps://api.your-backend.com/data?callbackhandleDatadocument.body.appendChild(script)优点兼容IE6-82026几乎不用缺点仅支持GET、不安全、无法发POST/PUT、无法处理错误适用极老系统、第三方不支持CORS的接口极少3.4 postMessageiframe/跨窗口通信专用方案3.4.1 适用场景页面嵌套iframe、多窗口window.open之间跨域通信。3.4.2 实战代码父页面a.com// 向子iframe发消息constiframedocument.getElementById(child-iframe)iframe.contentWindow.postMessage({type:hello,data:来自父页面},https://b.com// 必须指定子页面域名安全)// 监听子页面返回window.addEventListener(message,(e){// 安全校验必须验证来源if(e.origin!https://b.com)returnconsole.log(子页面消息:,e.data)})子iframe页面b.com// 监听父页面消息window.addEventListener(message,(e){if(e.origin!https://a.com)returnconsole.log(父页面消息:,e.data)// 回复消息e.source.postMessage({type:reply,data:收到了},e.origin)})安全铁律生产环境绝对不能用targetOrigin: *必须校验event.origin只信任指定域名优点HTML5标准、安全、双向通信缺点仅适用于窗口/iframe场景适用iframe嵌套、多窗口跨域通信3.5 其他方案了解3.5.1 document.domain主域相同子域跨域适用a.xxx.com和b.xxx.com// 两个页面都设置document.domainxxx.com即可互相访问DOM/Cookie。3.5.2 WebSocket实时通信无跨域WebSocket协议不受同源策略限制可直接跨域通信。constwsnewWebSocket(wss://api.your-backend.com/ws)适合聊天室、直播、实时数据推送。3.5.3 window.name/location.hash过时方案兼容性差、不安全、功能有限2026年基本淘汰了解即可。四、方案选型指南2026年最佳实践讲了这么多方案很多人懵了我到底该用哪个直接给你2026年最实用、最稳妥的选型结论照着选不出错4.1 开发环境本地调试首选Vite/Webpack 代理理由前端一键配置、无需后端配合、开发效率拉满、零成本解决跨域。4.2 生产环境自有服务、前后端分离首选CORS后端配置理由W3C标准、安全可控、支持所有请求、性能最好、无中间层损耗。备选Nginx反向代理理由后端不方便改配置、需要统一入口、隐藏后端地址、加负载均衡/限流。4.3 iframe/多窗口跨域通信唯一选择postMessage理由HTML5标准、安全、官方推荐、双向通信。4.4 调用第三方接口不可控支持CORS直接用CORS不支持CORS自己服务器搭一层代理前端→你的代理→第三方接口绝对别用JSONP。4.5 绝对禁忌生产环境禁止CORS用Access-Control-Allow-Origin: *带Cookie时完全失效、不安全禁止postMessage用targetOrigin: *极易被劫持禁止生产环境用JSONP仅GET、不安全禁止随意关闭浏览器同源策略本地调试偶尔用线上绝对不行五、常见跨域坑与避坑指南2026最新5.1 带Cookie跨域失败最常见原因三要素后端Access-Control-Allow-Credentials: true后端Access-Control-Allow-Origin必须指定具体域名不能用*前端请求必须带credentials: includefetch或withCredentials: trueaxios5.2 自定义请求头触发OPTIONS预检加了Token/Authorization等自定义头浏览器自动发OPTIONS。解决后端配置Access-Control-Allow-Headers包含自定义头并处理OPTIONS请求。5.3 端口号被忽略本地开发本地localhost:3000前端 →localhost:8080后端端口不同算跨域必须用代理或CORS。5.4 Nginx代理后Cookie丢失解决Nginx加配置proxy_cookie_domain backend.com your-site.com; proxy_set_header Cookie $http_cookie;5.5 浏览器缓存导致跨域异常解决清浏览器缓存、禁用缓存、加Cache-Control: no-cache。六、总结跨域其实很简单最后用几句话把全文浓缩方便你记忆同源 协议域名端口完全相同浏览器安全基石跨域拦截是浏览器干的服务器正常返回浏览器扔结果2026首选方案开发用代理、生产用CORS、iframe用postMessage安全第一生产别用*、校验origin、不用JSONP跨域不是难题懂原理、选对方案、规范配置轻松搞定跨域是前端开发的基础中的基础也是面试高频考点。把这篇文章吃透日常开发的跨域坑基本都能踩平面试也能从容应对。Web开发日新月异但同源策略和跨域的核心原理永远不变。掌握本质才能以不变应万变。P.S. 目前国内还是很缺AI人才的希望更多人能真正加入到AI行业共同促进行业进步增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow教程通俗易懂高中生都能看懂还有各种段子风趣幽默从深度学习基础原理到各领域实战应用都有讲解我22年的AI积累全在里面了。注意教程仅限真正想入门AI的朋友否则看看零散的博文就够了。