项目中遇到浏览器跨域前端和后端解决方案以及大概过程

前言: ‌浏览器出于安全考虑,要求请求的 ‌协议(HTTP/HTTPS)、域名、端口(如 90/455 ‌ 三者完全一致,否则视为跨域。跨域问题的本质是 ‌浏览器通过同源策略保护用户数据安全‌,强制要求前后端资源同源。开发中因为环境分离、多域名部署等场景就会触发该策略的拦截机制‌。

一. 纯前端解决方案

1. ‌本地开发环境推荐使用代理解决‌‌

1.在Vue/React项目中配置 vue.config.jswebpack.config.js(vue3中是vite.config.ts文件)

js 复制代码
//vue3的Vite示例
export default defineConfig({
  // 服务端渲染
    server: {
      // 端口号
      port: "8980",
      host: "0.0.0.0",
      // 本地跨域代理 http://192.145.1.95:1216
      proxy: {
        "/admin-api": {
          // 这里填写后端地址
          // target: "https://test.com",
          target: VITE_API_PATH, //或者封装起来
          changeOrigin: true,
          rewrite: path => path.replace(/^\/admin-api/, ""),
          secure: false // 验证 SSL 证书
        }
      },
    },
});
// vue2的webpack示例示例
module.exports = {
    devServer: {
        proxy: {
            '/admin-api': {
                target: 'https://test.com',
                changeOrigin: true
            }
        }
    }
};

// 不同的前端语言大致实现思路都一样

2.重启开发服务器,前端请求本地路径包含 /api 自动代理到后端接口地址。

2. ‌利用WebSocket协议解决‌‌

WebSocket 解决跨域的核心原理是在 HTTP 握手阶段通过服务器主动验证 Origin 字段完成跨域授权,而非依赖浏览器同源策略的默认拦截机制‌

1.前端使用WebSocket建立连接:

js 复制代码
const socket = new WebSocket('ws://test.com:9090');
socket.onmessage = (event) => { console.log(event.data); };

2.后端需实现WebSocket服务端(如Socket.io)。

3.postMessage(跨窗口通信)

1.父窗口向iframe子窗口发送消息

js 复制代码
const iframe = document.getElementById('child-frame');
iframe.contentWindow.postMessage('data', 'http://child.com');

2.子窗口监听消息:

js 复制代码
window.addEventListener('message', (event) => {
    if (event.origin === 'http://parent.com') console.log(event.data);
});

二. 后端解决方案

1. ‌CORS(跨域资源共享)--->生产环境推荐 ‌‌

1.后端在响应头中设置 Access-Control-Allow-Origin,允许指定源访问:

java 复制代码
// Spring Boot示例
@CrossOrigin(origins = "http://localhost:9090")
@GetMapping("/api/data")
public String getData() { /*...*/ }

2.若需携带Cookie,需设置 Access-Control-Allow-Credentials: true 并指定具体源(不能为*)。

3.预检请求(如PUT、DELETE)需处理OPTIONS方法,返回允许的HTTP方法和头信息。

2. ‌Nginx反向代理--->生产环境推荐‌‌

1.在Nginx配置文件中添加代理规则:

nginx 复制代码
server {
    listen 90;
    server_name frontend.com;
    location /api {
        proxy_pass http://test.com:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2.重启Nginx服务,使前端通过统一域名访问后端接口

3. ‌JSONP(仅GET请求) ‌‌

1.前端动态创建<script>标签,指定回调函数名:

js 复制代码
function handleData(data) { /*...*/ }
const script = document.createElement('script');
script.src = 'http://test.com/data?callback=handleData';
document.body.appendChild(script);

2.后端返回包裹回调函数的数据:

js 复制代码
handleData({ "result": "success" });

三、其他场景方案

同主域不同子域 ‌:设置 document.domain = 'test.com'(需主域相同)‌

IE兼容性‌:使用XDomainRequest对象替代XMLHttpRequest‌

结尾

推荐方案‌:生产环境优先使用CORS或Nginx反向代理‌,开发环境用本地代理‌更方便快捷(配置简单且无侵入性‌)

慎用方案‌:JSONP仅适用于简单GET请求且安全性较低‌(需注意XSS风险‌),postMessage适用于特定跨窗口场景‌。

如果兄弟们还有其他更方便的解决方案欢迎评论区讨论分享,具体实现还需根据项目来定最适合的解决方案

相关推荐
万少4 小时前
HarmonyOS 开发必会 5 种 Builder 详解
前端·harmonyos
橙序员小站6 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名9 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫9 小时前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊9 小时前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter9 小时前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
曲折9 小时前
Cesium-气象要素PNG色斑图叠加
前端·cesium
Forever7_10 小时前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js
Angelial10 小时前
Vue3 嵌套路由 KeepAlive:动态缓存与反向配置方案
前端·vue.js
jiayu10 小时前
Angular学习笔记24:Angular 响应式表单 FormArray 与 FormGroup 相互嵌套
前端