English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french
查看: 3|回复: 0

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

[复制链接]
查看: 3|回复: 0

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

[复制链接]
查看: 3|回复: 0

228

主题

0

回帖

694

积分

高级会员

积分
694
jO6rNgNS

228

主题

0

回帖

694

积分

高级会员

积分
694
2025-3-1 10:49:22 | 显示全部楼层 |阅读模式
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:全局配置(一劳永逸)@Configurationpublic class CorsConfig implements WebMvcConfigurer {    @Override    public 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: true2.5 WebSocket

适用场景:实时通信需求(聊天室、股票行情)。
WebSocket协议没有跨域限制(因为握手阶段走HTTP,后续升级为长连接)。
前端代码
const socket = new WebSocket('ws://api.xxx.com:8000/ws');socket.onmessage = (event) => {    console.log('收到消息:', event.data);};后端代码(Spring Boot)
@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {    @Override    public 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。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

228

主题

0

回帖

694

积分

高级会员

积分
694

QQ|智能设备 | 粤ICP备2024353841号-1

GMT+8, 2025-3-10 19:15 , Processed in 4.684504 second(s), 30 queries .

Powered by 智能设备

©2025

|网站地图