一.什么是跨域
跨域(Cross-Origin)是浏览器同源策略(Same-Origin Policy)的安全限制结果,只有当协议(如http/https)、域名(如www.example.com)和端口(如80)三者完全一致时,两个页面才被视为同源,才能自由共享资源;任何一项不同即构成跨域,浏览器会阻止脚本、AJAX请求等跨源访问。
1.端口不同

2.协议,域名不同

二、跨域的原因
浏览器的同源策略是造成跨域的主要原因。
同源策略是浏览器中的一种安全策略,保证当两个URL的协议、域名、端口有任何不同时,限制它们之间的交互。
不加限制则可能导致:恶意网页获取其它网页的数据、修改DOM、操作DOM获取用户输入的值、执行恶意脚本,读取Cookie、发送Ajax请求。
非跨域情况下,执行下面的代码可以做到修改DOM
let document2 = opener.document;
document2.body.style.display = "none";
三、如何解决跨域
1. JSONP(前端+后端)
不受同源策略影响的标签:
html
<img>, <script>, <link>, <iframe>
JSONP利用script标签,将请求放在src属性中,前端通过解析(一段JavaScript代码)拿到数据。
<script src="http://localhost:4000/getJSONP?fn=setJSONP"></script>
优点:
轻量、兼容性高,不需要XMLHttpRequest
缺点:
(1) 只支持GET,不支持POST;
(2) 存在被注入恶意脚本的风险
(3) 接口异常,无法监听
2、CORS(跨域资源共享)(后端)
后端设置响应头中的 Access-Control-Allow-Origin 字段,该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
示例:
res.header('Access-Control-Allow-Origin', '*')
// 或指定域名:
// res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
优点:
操作简单,支持所有 HTTP 请求类型(GET、POST、PUT 等)
缺点:
IE8 以下的浏览器不支持
3.代理转发(前端+nginx)
同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true, // 是否开启跨域,值为 true 就是开启,false 不开启
pathRewrite: {
'/api': ''
}
}
}
}
})
把你的实际请求转到了本地运行的服务,再转发到后端地址,从而跳过了浏览器及其同源策略,也就不会跨域。
ngix配置
server {
listen 5000;
server_name localhost;
location /api {
add_header Access-Control-Allow-Origin 'http://localhost:3000';
proxy_pass http://localhost:4000;
}
}
4. postMessage
postMessage 是 HTML5 中新增的跨文档消息传递机制,是为数不多可以跨域操作的 window 属性之一,它可用于解决以下方面的问题:
a). 页面和其打开的新窗口的数据传递
b). 多窗口之间消息传递
c). 页面与嵌套的 iframe 消息传递
d). 上面三个场景的跨域数据传递
通过postmessage方法传递消息,基本使用:
发送消息
// targetWindow: 目标窗口的引用(如 iframe.contentWindow, window.open 返回的对象, window.parent 等)
// message: 要发送的数据(字符串或对象)
// targetOrigin: 目标窗口的源(协议+主机+端口),用于安全验证
targetWindow.postMessage(message, targetOrigin);
接收消息
window.addEventListener('message', function(event) {
// event.data: 接收到的数据
// event.origin: 发送消息的窗口的源
// event.source: 发送消息的窗口对象的引用
// 安全验证:检查来源是否可信
if (event.origin !== 'https://trusted-domain.com') {
return;
}
console.log('收到消息:', event.data);
// 可选:回复消息
event.source.postMessage('收到', event.origin);
});
适用场景总结
跨域 iframe 通信 - 主页面与不同域的 iframe 交互
多窗口应用 - 多个标签页或窗口间同步数据
微前端架构 - 不同技术栈的子应用间通信
第三方插件/组件 - 嵌入的第三方组件与主应用通信
单点登录(SSO) - 不同域的子系统间传递认证信息
postMessage 是浏览器原生支持的跨域通信方案,无需服务器参与,是实现跨域实时通信的有效手段。
日常开发中我们最常用的是2和3来处理跨域问题。
PS: 在实现微前端的过程中,由于基座和子项目分别跑到不同的端口下,就会存在跨域的问题.
开发环境下,为了方便调试可以使用chrome的跨域插件来辅助开发。
跨域插件:allow-cors-access-control插件
