当前位置: 首页 > news >正文

跨域(CORS)的几种方式

1. CORS(跨域资源共享)

原理:服务器设置 HTTP 响应头,允许指定来源访问资源。
适用场景:前后端分离项目(主流方案)。

服务器端设置(以 Node.js 为例)

const express = require('express');
const app = express();// 允许所有来源访问(生产环境应限制为具体域名)
app.use((req, res, next) => {res.header('Access-Control-Allow-Origin', '*'); // 或 'https://example.com'res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');next();
});app.get('/api/data', (req, res) => {res.json({ message: 'CORS 允许跨域访问' });
});app.listen(3000);

说明

  • Access-Control-Allow-Origin:允许的域名(* 表示所有)。

  • Access-Control-Allow-Methods:允许的 HTTP 方法。

  • Access-Control-Allow-Headers:允许的请求头。


2. JSONP(仅 GET 请求)

原理:利用 <script> 标签不受同源策略限制的特性,动态创建 script 请求数据。
适用场景:仅支持 GET 请求,老旧浏览器兼容方案。

前端代码

function jsonp(url, callbackName) {const script = document.createElement('script');script.src = `${url}?callback=${callbackName}`;document.body.appendChild(script);
}// 定义回调函数
function handleResponse(data) {console.log('JSONP 返回数据:', data);
}// 调用 JSONP
jsonp('http://example.com/api/data', 'handleResponse');

服务器端代码(Node.js)

app.get('/api/data', (req, res) => {const callbackName = req.query.callback;const data = { message: 'JSONP 返回数据' };res.send(`${callbackName}(${JSON.stringify(data)})`);
});

缺点

  • 仅支持 GET 请求。

  • 安全性较低(容易遭受 XSS 攻击)。


 

3. 代理服务器(Proxy)

原理:前端请求同域代理服务器,代理服务器转发请求到目标服务器。
适用场景:开发环境(如 webpack-dev-server)或 Nginx 反向代理。

(1)Webpack DevServer 代理

// vue.config.js / webpack.config.js
module.exports = {devServer: {proxy: {'/api': {target: 'http://example.com', // 目标服务器changeOrigin: true, // 修改请求头 HostpathRewrite: { '^/api': '' }, // 重写路径},},},
};

前端请求 /api/data 会被代理到 http://example.com/data

(2)Nginx 反向代理

server {listen 80;server_name localhost;location /api {proxy_pass http://example.com; # 目标服务器proxy_set_header Host $host;}
}

访问 http://localhost/api/data 会被代理到 http://example.com/api/data


 

4. WebSocket

原理:WebSocket 不受同源策略限制,可用于跨域通信。
适用场景:实时通信(如聊天室、股票行情)。

前端代码

const socket = new WebSocket('ws://example.com/socket');socket.onmessage = (event) => {console.log('WebSocket 消息:', event.data);
};

服务器端(Node.js + ws 库)

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', (ws) => {ws.send('WebSocket 连接成功');
});

 

5. postMessage(跨窗口通信)

原理window.postMessage 允许不同源的窗口间通信。
适用场景:iframe 跨域通信、多窗口交互。

父窗口(http://parent.com)

const iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage('Hello from parent!', 'http://child.com');

 子窗口(http://child.com)

window.addEventListener('message', (event) => {if (event.origin !== 'http://parent.com') return; // 验证来源console.log('收到消息:', event.data);
});

6. document.domain(仅适用于主域相同)

原理:修改 document.domain 使子域之间可以通信。
适用场景a.example.com 和 b.example.com 之间的通信。

前端代码

// 在 a.example.com 和 b.example.com 都设置
document.domain = 'example.com';

限制

  • 仅适用于主域相同的情况(如 a.example.com 和 b.example.com)。

  • 现代浏览器已逐渐废弃此方法。


 

7. 浏览器禁用安全策略(仅开发环境)

方法:启动浏览器时关闭安全策略(不推荐生产环境使用)。
示例(Chrome)

chrome.exe --disable-web-security --user-data-dir="C:\Temp"

风险:可能导致安全问题,仅用于本地测试。


总结 

推荐方案

  • 生产环境:使用 CORS(主流方案)或 Nginx 代理

  • 开发环境:使用 Webpack 代理 或 CORS

  • 特殊需求:WebSocket(实时通信)、postMessage(跨窗口通信)。

相关文章:

  • 双重路由引入的环路,选路次优的产生以及解决方法
  • 2025最新版flink2.0.0安装教程(保姆级)
  • 层次式架构核心:中间层的功能、优势与技术选型全解析
  • Oracle中用户密码过期修改为不限制
  • Linux系统-scp命令--两台服务器之间传输文件
  • 利用纯JS开发浏览器小窗口移动广告小功能
  • 通过微信APPID获取小程序名称
  • Spring 框架知识整理
  • K8S_ResourceQuota与LimitRange的作用
  • Materials Studio学习笔记(一)——Materials Studio软件介绍
  • Flutter学习 滚动组件(1):ListView基本使用
  • 【差分隐私相关概念】瑞丽差分隐私(RDP)命题4
  • 宝塔面板中解锁Laravel日志查看的奥秘
  • pull.rebase 三种模式的应用场景
  • java的类加载器及其双亲委派机制
  • 解决docker安装OpenWebUI 报错 500
  • Node.js 数据库 CRUD 项目示例
  • uni-app/微信小程序接入腾讯位置服务地图选点插件
  • STM32F407实现SD卡的读写功能
  • #[特殊字符]Rhino建模教程 · 第一章:正方体建模入门
  • 文旅部副部长饶权出任国家文物局局长
  • 锚定“双一流”战略坐标,福建农林大学向全球英才“伸出橄榄枝”
  • 蜀道考古调查阶段性成果发布,新发现文物遗存297处
  • “爱泼斯坦案”关键证人弗吉尼亚·朱弗雷自杀身亡
  • 证监会发布上市公司信披豁免规定:明确两类豁免范围、规定三种豁免方式
  • 商务部就海外社交平台上发布从所谓中国“代工厂”低价购买国际知名品牌事答问