解决跨域问题的这6种方案,真香!

news/2025/3/1 10:19:15/文章来源:https://www.cnblogs.com/12lisu/p/18744568

1 什么事跨域问题?

很多小伙伴第一次遇到跨域问题,大概率会一脸懵逼:“我后端接口明明通了,Postman也能调,为啥浏览器就报红字?”

其实这事儿得怪浏览器的“同源策略”(Same-Origin Policy)。

简单说,浏览器觉得“不同源的请求都是耍流氓”。

比如你的前端跑在http://localhost:8080。

而后端在https://api.xxx.com:8000。

只要协议域名端口任何一个不同,就会被浏览器直接掐断。

举个栗子🌰:

// 前端代码(http://localhost:8080)
fetch('http://api.xxx.com:8000/user').then(res => res.json()).then(data => console.log(data));  
// 浏览器控制台报错:  
// Access to fetch from 'http://localhost:8080' has been blocked by CORS policy...

这时候,你就需要“跨域解决方案”来帮浏览器松绑了!

那么,如何解决跨域问题呢?

2 解决跨域问题的方案

2.1 CORS(跨域资源共享)

适用场景:前后端分离项目、接口需要兼容多种客户端。

CORS是W3C标准,后端只需在响应头里加几个字段,告诉浏览器“这个接口我允许谁访问”

后端代码示例(Spring Boot版)

// 方法1:直接怼注解(适合单个接口)
@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/user")
public User getUser() { ... }// 方法2:全局配置(一劳永逸)
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://localhost:8080").allowedMethods("*").allowedHeaders("*").allowCredentials(true).maxAge(3600);}
}

关键响应头

  • Access-Control-Allow-Origin: http://localhost:8080(允许的源)
  • Access-Control-Allow-Methods: GET,POST(允许的方法)
  • Access-Control-Allow-Credentials: true(允许带Cookie)

注意坑点

  • 如果用了allowCredentials(true)allowedOrigins不能为*(必须明确指定域名)。
  • 复杂请求(比如Content-Type是application/json)会先发一个OPTIONS预检请求,记得处理!

2.2 JSONP

适用场景:老项目兼容、只支持GET请求(比如调用第三方地图API)。

JSONP利用<script>标签没有跨域限制的特性,让后端返回一段JS代码。

前端代码

function handleUserData(data) {console.log("收到数据:", data);
}// 动态创建script标签
const script = document.createElement('script');
script.src = 'http://api.xxx.com:8000/user?callback=handleUserData';
document.body.appendChild(script);

后端代码

@GetMapping("/user")
public String jsonp(@RequestParam String callback) {User user = new User("Tony", 30);// 把数据包进回调函数里return callback + "(" + new Gson().toJson(user) + ")";
}

输出结果

handleUserData({"name":"Tony","age":30})  

缺点

  • 只支持GET(传参长度有限)。
  • 容易被XSS攻击(毕竟得信任第三方脚本)。

2.3 Nginx反向代理

适用场景:生产环境部署、微服务网关统一处理。

直接把跨域问题甩给Nginx,让浏览器以为所有请求都是同源的。

Nginx配置示例

server {listen 80;server_name localhost;location /api {# 转发到真实后端proxy_pass http://api.xxx.com:8000;# 解决跨域add_header 'Access-Control-Allow-Origin' 'http://localhost:8080';add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';add_header 'Access-Control-Allow-Headers' 'Content-Type';}
}

此时前端请求地址改成同源

fetch('/api/user')  // 实际访问 http://localhost/api/user → 被Nginx转发

优点

  • 前后端代码零侵入。
  • 能隐藏真实接口地址(安全加分)。

2.4 网关层统一处理

适用场景:Spring Cloud Gateway、Kong等API网关。

和Nginx思路类似,但更适合微服务场景,直接在网关层加CORS配置。

Spring Cloud Gateway配置

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowed-origins: "http://localhost:8080"allowed-methods: "*"allowed-headers: "*"allow-credentials: true

2.5 WebSocket

适用场景:实时通信需求(聊天室、股票行情)。

WebSocket协议没有跨域限制(因为握手阶段走HTTP,后续升级为长连接)。

前端代码

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

后端代码(Spring Boot)

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new MyWebSocketHandler(), "/ws");}
}

2.6 PostMessage

适用场景:页面与iframe、弹窗之间的跨域通信。

通过window.postMessage实现不同窗口间的数据传递。

父页面(http://parent.com)

const childWindow = window.open('http://child.com');
childWindow.postMessage('我是你爹', 'http://child.com');

子页面(http://child.com)

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

总结

  • 简单粗暴:开发环境用CORS注解。
  • 生产环境:优先Nginx/网关统一处理,避免每个服务配一遍。
  • 老项目兼容:JSONP勉强能用,但别长期依赖。
  • 实时场景:直接上WebSocket,顺便解决通信问题。
  • 安全第一Access-Control-Allow-Origin尽量别写*,白名单要用精确域名。

最后提醒温馨提醒一下:跨域问题本质是浏览器行为,和HTTP协议无关。

如果你用Postman,发送curl请求,测试没问题,但浏览器报错,别怀疑人生,这可能是前端的锅!

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/891468.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch内存优化的10种策略总结:在有限资源环境下高效训练模型

在大规模深度学习模型训练过程中,GPU内存容量往往成为制约因素,尤其是在训练大型语言模型(LLM)和视觉Transformer等现代架构时。由于大多数研究者和开发者无法使用配备海量GPU内存的高端计算集群,因此掌握有效的内存优化技术变得尤为关键。本文将系统性地介绍多种内存优化策…

安川机器人电路板维修的重要性

在现代工业生产中,安川机器人扮演着极为重要的角色。然而,如同任何设备一样,安川机器人也会面临故障问题。其中,电路板故障是较为常见的情况,安川机器人电路板维修成为保障机器人正常工作的关键环节,这也与整个工业机器人维修领域息息相关。二、安川机器人故障与电路板维…

多项式全文背诵

不要把技能树点歪了。 math-数学前置 复数 \(x+yi\) 的数称为复数,其中 \(i = \sqrt{-1}\)。 一般把复数放到复平面上,那么复数 \(x+yi\) 就可以看做一个平面向量 \(\large{x \brack y}\),用两个 double 存一下就好了。 乘法运算法则:\((x+yi)(x+yi)=(xx-yy)+(xy+xy)i\) 单…

vSphere 使用Lifecycle Manager升级ESXI报错处理

背景:需要将ESXI7.0版本升级到ESXI8.0版本,不想通过IDRAC或者U盘升级,找到的方案说Lifecycle Manager可以升级,但是在升级中出现了一个警告,特记录处理步骤1.异常报错信息 详细信息: 升级中包含具有缺少依赖项的 VIB: MEL_bootbank_mft_4.25.0.703-0 MEL_bootbank_nmst_4…

VMware 使用Lifecycle Manager升级ESXI报错处理

背景:需要将ESXI7.0版本升级到ESXI8.0版本,不想通过IDRAC或者U盘升级,找到的方案说Lifecycle Manager可以升级,但是在升级中出现了一个警告,特记录处理步骤1.异常报错信息 详细信息: 升级中包含具有缺少依赖项的 VIB: MEL_bootbank_mft_4.25.0.703-0 MEL_bootbank_nmst_4…

JS调用web hid api接口驱动RFID读卡器读取IC卡号

`<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Web HID Api IC卡读卡器Demo</title> <script language="javasc…

5. Nginx 负载均衡配置案例(附有详细截图说明++)

5. Nginx 负载均衡配置案例(附有详细截图说明++) @目录5. Nginx 负载均衡配置案例(附有详细截图说明++)1. Nginx 负载均衡 配置实例3. 注意事项和避免的坑4. 文档: Nginx 的 upstream 配置技巧5. 最后:1. Nginx 负载均衡 配置实例 需求说明/图解 windows 浏览器输入: http://w…

微信接入DeepSeek引发的生态核爆

微信接入DeepSeek的举动引发了行业内外的广泛关注,这一看似仓促的灰度测试背后,可能隐藏着腾讯对AI生态布局的深远考量。本文从多个角度剖析了微信接入DeepSeek的潜在影响,供大家参考。当微信搜索框底部的”AI搜索”入口悄然浮现,这场酝酿已久的生态革命终于撕开帷幕。作为…

Splunk Enterprise 9.4.1 (macOS, Linux, Windows) - 机器数据管理和分析

Splunk Enterprise 9.4.1 (macOS, Linux, Windows) - 机器数据管理和分析Splunk Enterprise 9.4.1 (macOS, Linux, Windows) - 机器数据管理和分析 安全信息和事件管理 (SIEM)、全面的日志管理和分析平台 请访问原文链接:https://sysin.org/blog/splunk-9/ 查看最新版。原创作…

一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库

前言 今天大姚给大家分享一套基于 Material Design 规范实现的、开源(MIT license)且免费的 Blazor 和 Razor 通用组件库:MatBlazor。 Blazor介绍 Blazor 是基于 HTML、CSS 和 C# 的现代前端 Web 框架,可帮助你更快地生成 Web 应用。使用 Blazor,你可以使用可从客户端和服…