news 2026/4/14 21:20:23

跨域基础:浏览器同源策略与解决方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
跨域基础:浏览器同源策略与解决方案

文章目录

    • 前言
    • 一、同源策略:浏览器的"安全门卫"
      • 1.1 什么是同源?先搞懂"三兄弟"
      • 1.2 浏览器为啥要搞同源策略?安全第一!
    • 二、跨域本质:浏览器拦的,不是服务器
    • 三、2026年主流跨域解决方案(全场景覆盖)
      • 3.1 CORS:现代Web跨域"标准之王"(最推荐)
        • 3.1.1 什么是CORS?
        • 3.1.2 CORS工作流程(极简版)
        • 3.1.3 简单请求 vs 预检请求(OPTIONS)
        • 3.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 postMessage:iframe/跨窗口通信"专用方案"
        • 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.html
    • https://www.baidu.com/api/user✅ 同源(协议、域名、端口全一样)
    • http://www.baidu.com/api/user❌ 不同源(协议不同:https vs http)
    • https://map.baidu.com/api❌ 不同源(子域名不同:www vs map)
    • https://www.baidu.com:8080/api❌ 不同源(端口不同:默认443 vs 8080)
    • https://baidu.com/api❌ 不同源(域名不同:www.baidu.com vs baidu.com)

简单记:协议、域名、端口,一个都不能少。少一个、变一个,浏览器就不认你是自己人。

1.2 浏览器为啥要搞同源策略?安全第一!

很多新手吐槽:同源策略太烦了,限制这限制那,直接关掉不香吗?

大错特错!同源策略是浏览器的"安全门卫",没有它,你上网就等于裸奔。

我给你打个比方:
你登录了银行网站(bank.com),Cookie里存了登录态。这时候你不小心点开一个恶意网站(hacker.com)。如果没有同源策略,恶意网站的JS就能直接读取你银行网站的Cookie、获取你的账户信息、甚至偷偷发起转账请求——你的钱瞬间就没了。

同源策略的核心目的,就是隔离不同源的资源,防止恶意网站窃取数据、伪造请求、篡改DOM。它主要限制三件事:

  1. AJAX/Fetch请求限制:不同源的接口,直接请求会被浏览器拦截,控制台报错
  2. DOM访问限制:不同源的iframe/窗口,不能互相读取DOM、调用方法
  3. 存储访问限制:不同源不能读取对方的Cookie、LocalStorage、IndexedDB

一句话总结:同源策略是浏览器的安全底线,跨域问题是安全与开发便利的矛盾产物。我们要做的,不是打破安全,而是在安全框架内,找到合法合规的"通行证"。

二、跨域本质:浏览器拦的,不是服务器

这里有个超级关键的点,90%的新手都搞混:跨域拦截,是浏览器干的,跟服务器没关系!

我再强调一遍:

  • 服务器收到跨域请求,正常处理、正常返回数据
  • 浏览器拿到服务器返回的结果,检查是否符合同源策略
  • 不符合,浏览器直接把数据扔掉,抛给你一个跨域错误
  • 服务器全程不知道自己的响应被浏览器丢了

这就好比:
你(浏览器)去快递站(服务器)取快递(数据)。快递站不管你是谁,把包裹给你了。但你回家路上,被小区保安(同源策略)拦住了:“这个包裹不是你家(同源)的,不能带进小区!” 于是你只能把包裹扔了,还跟主人(前端代码)说:“取不到,被拦了!”

所以:

  • 服务器没毛病,响应正常
  • 问题出在浏览器的安全校验
  • 解决跨域,本质就是让浏览器知道:这个跨域请求是合法的、被允许的

三、2026年主流跨域解决方案(全场景覆盖)

3.1 CORS:现代Web跨域"标准之王"(最推荐)

3.1.1 什么是CORS?

CORS(Cross-Origin Resource Sharing,跨域资源共享),是W3C官方标准,2026年开发首选、最规范、最安全的跨域方案

原理一句话:服务器通过HTTP响应头,告诉浏览器:“这个来源我允许访问,放行!”

3.1.2 CORS工作流程(极简版)
  1. 浏览器发起跨域请求,自动在请求头加Origin: 当前域名
  2. 服务器收到请求,检查Origin是否在白名单
  3. 允许:返回Access-Control-Allow-Origin: 允许的域名
  4. 浏览器检查响应头,匹配成功:把数据给前端
  5. 不允许:浏览器拦截,抛跨域错误
3.1.3 简单请求 vs 预检请求(OPTIONS)

CORS分两种请求,面试必考:

① 简单请求(满足两个条件)

  • 方法: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 # 是否允许携带Cookie(true时,Allow-Origin不能用*) Access-Control-Allow-Credentials: true # 预检缓存时间(秒),减少OPTIONS请求 Access-Control-Max-Age: 86400
3.1.5 实战代码(Express+前端)

后端(Express)

// 全局CORS中间件(生产建议用cors库)app.use((req,res,next)=>{// 允许的前端域名constallowOrigin=['https://www.a.com','https://www.b.com']constorigin=req.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.method==='OPTIONS'){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 原理(最容易理解)

同源策略只限制浏览器,服务器之间通信没有跨域

代理方案:

  1. 前端 → 请求同源代理地址(如/api/xxx
  2. 代理服务器(本地/Vite/Nginx)→ 转发到真实后端
  3. 代理服务器拿到响应 → 返回给前端
  4. 浏览器以为是同源请求,直接放行
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/user,Nginx转发到后端,浏览器全程以为是同源。

优点:前端无感知、彻底解决跨域、安全、可加限流/负载均衡
缺点:需配置代理服务器
适用:开发环境调试、生产环境统一入口

3.3 JSONP:兼容老浏览器的"上古方案"(了解即可)

3.3.1 原理

利用<script>标签不受同源策略限制的特性:

  1. 前端动态创建<script src="https://api.com?callback=handleData">
  2. 服务器返回:handleData({ name:"张三" })(JS函数调用)
  3. 浏览器加载执行,前端拿到数据
3.3.2 实战代码
// 前端functionhandleData(data){console.log('拿到数据:',data)}constscript=document.createElement('script')script.src='https://api.your-backend.com/data?callback=handleData'document.body.appendChild(script)

优点:兼容IE6-8(2026几乎不用)
缺点:仅支持GET、不安全、无法发POST/PUT、无法处理错误
适用:极老系统、第三方不支持CORS的接口(极少)

3.4 postMessage:iframe/跨窗口通信"专用方案"

3.4.1 适用场景

页面嵌套iframe、多窗口(window.open)之间跨域通信。

3.4.2 实战代码

父页面(a.com)

// 向子iframe发消息constiframe=document.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.comb.xxx.com

// 两个页面都设置document.domain='xxx.com'

即可互相访问DOM/Cookie。

3.5.2 WebSocket:实时通信无跨域

WebSocket协议不受同源策略限制,可直接跨域通信。

constws=newWebSocket('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 绝对禁忌(生产环境)

  1. 禁止CORS用Access-Control-Allow-Origin: *(带Cookie时完全失效、不安全)
  2. 禁止postMessage用targetOrigin: *(极易被劫持)
  3. 禁止生产环境用JSONP(仅GET、不安全)
  4. 禁止随意关闭浏览器同源策略(本地调试偶尔用,线上绝对不行)

五、常见跨域坑与避坑指南(2026最新)

5.1 带Cookie跨域失败(最常见)

原因三要素

  1. 后端Access-Control-Allow-Credentials: true
  2. 后端Access-Control-Allow-Origin必须指定具体域名,不能用*
  3. 前端请求必须带credentials: include(fetch)或withCredentials: true(axios)

5.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

六、总结:跨域其实很简单

最后,用几句话把全文浓缩,方便你记忆:

  1. 同源 = 协议+域名+端口完全相同,浏览器安全基石
  2. 跨域拦截是浏览器干的,服务器正常返回,浏览器扔结果
  3. 2026首选方案:开发用代理、生产用CORS、iframe用postMessage
  4. 安全第一:生产别用*、校验origin、不用JSONP
  5. 跨域不是难题,懂原理、选对方案、规范配置,轻松搞定

跨域是前端开发的基础中的基础,也是面试高频考点。把这篇文章吃透,日常开发的跨域坑基本都能踩平,面试也能从容应对。

Web开发日新月异,但同源策略和跨域的核心原理永远不变。掌握本质,才能以不变应万变。

P.S. 目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步,增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow,教程通俗易懂,高中生都能看懂,还有各种段子风趣幽默,从深度学习基础原理到各领域实战应用都有讲解,我22年的AI积累全在里面了。注意,教程仅限真正想入门AI的朋友,否则看看零散的博文就够了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 21:19:46

自动化数据分发系统:按种牛将总统计表数据分发至独立统计表(支持动态追加与自动去重)

自动化数据分发系统:按种牛将总统计表数据分发至独立统计表(支持动态追加与自动去重) 1. 问题描述与需求分析 在畜牧业数据管理中,通常需要维护一个包含所有种牛生产、繁殖、健康等记录的“总统计表”。随着业务增长,数据量不断累积,经常需要将总表中的记录按照“种牛编…

作者头像 李华
网站建设 2026/4/14 21:16:37

ExtractorSharp终极指南:3步成为游戏资源编辑专家 [特殊字符]

ExtractorSharp终极指南&#xff1a;3步成为游戏资源编辑专家 &#x1f3ae; 【免费下载链接】ExtractorSharp Game Resources Editor 项目地址: https://gitcode.com/gh_mirrors/ex/ExtractorSharp ExtractorSharp是一款专业的游戏资源编辑器&#xff0c;专为Windows游…

作者头像 李华
网站建设 2026/4/14 21:07:34

vLLM-v0.17.1部署案例:vLLM服务与企业LDAP/OAuth2单点登录集成

vLLM-v0.17.1部署案例&#xff1a;vLLM服务与企业LDAP/OAuth2单点登录集成 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库&#xff0c;以其出色的吞吐量和易用性著称。这个开源项目最初由加州大学伯克利分校的天空计算实验室开发&#xff0c;现已…

作者头像 李华
网站建设 2026/4/14 21:05:33

终极指南:使用Legacy-iOS-Kit让旧iPhone/iPad重获新生

终极指南&#xff1a;使用Legacy-iOS-Kit让旧iPhone/iPad重获新生 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …

作者头像 李华
网站建设 2026/4/14 21:05:33

DAMOYOLO-S部署案例:中小企业零运维负担的目标检测SaaS接入方式

DAMOYOLO-S部署案例&#xff1a;中小企业零运维负担的目标检测SaaS接入方式 1. 引言&#xff1a;当目标检测遇上“开箱即用” 想象一下&#xff0c;你的电商平台每天要审核成千上万的商品图片&#xff0c;确保没有违禁品&#xff1b;你的工厂质检员需要从监控视频里找出有瑕疵…

作者头像 李华