同源策略是浏览器强制执行的铁律,跨域即其直接结果;三要素(协议、域名、端口)任一不同即跨域,路径不参与判定;仅资源加载本身放行,读取响应等操作均被拦截,cors和postmessage是合法解法。

跨域不是“影响”同源策略,而是同源策略直接定义了什么是跨域——它本身是浏览器强制执行的铁律,不存在“影响大不大”的问题。所有跨域行为都是同源策略生效后的自然结果。
同源策略判断标准必须同时满足三要素
协议、域名、端口号三者完全一致才算同源。任意一项不同,浏览器就认定为跨域,并立即施加限制:
-
https://a.com和http://a.com→ 协议不同,跨域 -
a.com和www.a.com→ 域名不同(严格比对 host),跨域 -
a.com:8080和a.com→ 端口显式 vs 隐式(http默认 80),跨域 -
a.com/path1和a.com/path2→ 路径不同,但同源(路径不参与同源判定)
注意:document.domain 只能在子域间降级使用(如 a.b.com 和 c.b.com 同时设为 b.com),且仅对 cookie 和 iframe DOM 访问有效,对 fetch/XMLHttpRequest 无效。
哪些操作会被同源策略拦截
不是所有跨域请求都会失败,关键看“脚本是否试图读取响应”:
-
fetch('https://api.other.com/data')→ 请求能发出去,但响应被浏览器拦截,response.text()抛TypeError: Failed to fetch -
<img src="https://cdn.other.com/pic.jpg?x-oss-process=image/resize,p_40">→ 允许加载,但 JS 无法读取像素数据(canvas.drawImage()会触发SecurityError) -
<script src="https://lib.other.com/sdk.js"></script>→ 允许执行,但该脚本内部发起的fetch仍受同源策略约束 -
iframe加载跨域页面 →iframe.contentWindow和iframe.contentDocument访问直接报SecurityError
真正“放行”的只有资源加载行为本身;一旦涉及读取、写入、DOM 访问或响应体解析,同源策略立刻介入。
CORS 是唯一由服务端配合解禁响应读取的正统方案
前端无法绕过同源策略,只能依赖后端配合。CORS(Cross-Origin Resource Sharing)通过响应头控制是否允许跨域读取:
- 简单请求(如
GET+text/plain)只需服务端返回Access-Control-Allow-Origin: *或指定域名 - 带认证的请求(
credentials: true)必须返回具体域名,不能用*,且需额外加Access-Control-Allow-Credentials: true - 非简单请求(如
PUT、自定义 header)会先发OPTIONS预检,服务端必须正确响应预检头
漏配任一响应头,浏览器就拒绝把响应交给 JS——这不是前端代码能 hack 的边界,是渲染引擎底层拦截。
iframe 跨域通信必须双方主动协作
想让父页和跨域 iframe 交换数据,不能靠 DOM 直接访问,只能用 window.postMessage():
- 发送方调用
iframe.contentWindow.postMessage(data, targetOrigin),targetOrigin必须精确(如https://child.example.com),不能写*(除非你确定对方没敏感逻辑) - 接收方在
window.addEventListener('message', handler)中检查event.origin是否可信,再处理event.data - 若 iframe 页面本身不监听
message,或父页没调用postMessage,通信即失效——没有自动 fallback
这要求两端代码都修改,且部署同步。任何一方未适配,通信就断在第一步。
同源策略不是配置项,是浏览器内核级硬约束。所谓“解决跨域”,本质是找到被允许的通道(CORS、postMessage、代理等),而不是绕过它。最容易被忽略的是:即使请求发出去了,只要没拿到响应体,就等于没成功——别只盯着 Network 面板里 status 200,要看 JS 是否真能 await res.json()。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











