处理Spring MVC 中的跨域问题

在 Spring MVC 中,跨域问题指的是浏览器从一个域名的网页去请求另一个域名的资源时,由于浏览器的同源策略而受到限制。同源策略要求浏览器在访问资源时,协议、域名和端口都必须相同,否则会产生跨域问题。以下是几种常见的处理 Spring MVC 中跨域问题的方法:

1. 使用 CORS(跨域资源共享)注解

原理

CORS 是一种现代的跨域解决方案,通过在服务器端设置响应头来允许跨域请求。Spring MVC 提供了@CrossOrigin注解,可以方便地在控制器或方法上启用 CORS 支持。

示例代码
复制代码
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
// 允许所有来源的跨域请求
@CrossOrigin(origins = "*") 
public class CorsController {

    @GetMapping("/cors")
    public String corsTest() {
        return "This is a CORS enabled endpoint.";
    }
}
详细解释
  • @CrossOrigin注解可以应用在类或方法上。当应用在类上时,该类中的所有方法都将允许跨域请求;当应用在方法上时,只有该方法允许跨域请求。
  • origins属性指定允许访问该资源的外域 URI。设置为"*"表示允许所有来源的跨域请求,但在生产环境中,建议指定具体的域名,以提高安全性。

2. 配置全局 CORS 映射

原理

除了使用@CrossOrigin注解,还可以通过配置全局的 CORS 映射来处理跨域问题。这种方式可以统一管理所有控制器的跨域配置。

示例代码
复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许所有域名进行跨域调用
        config.addAllowedOriginPattern("*"); 
        // 允许任何请求头
        config.addAllowedHeader("*"); 
        // 允许任何方法(POST、GET等)
        config.addAllowedMethod("*"); 
        // 允许携带凭证(如Cookie)
        config.setAllowCredentials(true); 

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有接口都有效
        source.registerCorsConfiguration("/**", config); 

        return new CorsFilter(source);
    }
}
详细解释
  • CorsConfiguration类用于配置 CORS 的相关信息,如允许的来源、请求头、请求方法等。
  • addAllowedOriginPattern("*"):允许所有域名进行跨域调用。在 Spring 5 及以上版本中,建议使用addAllowedOriginPattern而不是addAllowedOrigin,因为addAllowedOrigin不支持*和携带凭证同时使用。
  • addAllowedHeader("*"):允许任何请求头。
  • addAllowedMethod("*"):允许任何请求方法,如 GET、POST 等。
  • setAllowCredentials(true):允许携带凭证(如 Cookie)进行跨域请求。
  • UrlBasedCorsConfigurationSource用于将 CORS 配置映射到具体的 URL 路径上,这里将配置应用到所有接口("/**")。
  • CorsFilter是一个过滤器,用于处理跨域请求。

3. 使用 JSONP(JSON with Padding)

原理

JSONP 是一种传统的跨域解决方案,它利用了<script>标签的src属性不受同源策略限制的特点。服务器返回的数据会被包装在一个回调函数中,客户端通过<script>标签请求该数据,从而实现跨域数据传输。

示例代码
复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JsonpController {

    @GetMapping("/jsonp")
    public String jsonpTest(@RequestParam("callback") String callback) {
        String jsonData = "{\"message\": \"This is a JSONP response.\"}";
        return callback + "(" + jsonData + ")";
    }
}
详细解释
  • 客户端请求时需要传递一个回调函数名作为参数(通常命名为callback)。
  • 服务器接收到请求后,将返回的数据包装在该回调函数中,并返回给客户端。
  • 客户端的<script>标签会执行该回调函数,从而获取到服务器返回的数据。
客户端代码示例
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSONP Example</title>
    <script>
        function handleResponse(data) {
            console.log(data.message);
        }
    </script>
</head>
<body>
    <script src="http://localhost:8080/jsonp?callback=handleResponse"></script>
</body>
</html>

4. 使用代理服务器

原理

在开发环境中,可以使用代理服务器来解决跨域问题。代理服务器与前端页面处于同一域名下,前端页面向代理服务器发送请求,代理服务器再将请求转发到目标服务器,并将响应返回给前端页面。

示例:使用 Webpack Dev Server 进行代理

webpack.config.js中进行如下配置:

复制代码
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html - webpack - plugin');

module.exports = {
    // 其他配置...
    devServer: {
        proxy: {
            '/api': {
                target: 'http://backend-server.com', 
                changeOrigin: true,
                pathRewrite: { '^/api': '' }
            }
        }
    },
    // 其他配置...
};
详细解释
  • target:指定目标服务器的地址。
  • changeOrigin:设置为true表示在转发请求时改变请求的源地址,以避免服务器端的一些限制。
  • pathRewrite:用于重写请求路径,将/api前缀去掉。

不同方法的适用场景和优缺点

  • CORS 注解和全局 CORS 映射:适用于现代 Web 应用开发,是推荐的跨域解决方案。优点是简单易用,支持多种配置选项,安全性较高;缺点是需要服务器端支持,对于一些旧的浏览器可能不兼容。
  • JSONP :适用于需要兼容旧浏览器的场景。优点是兼容性好;缺点是只支持 GET 请求,安全性较低,因为它是通过<script>标签实现的,可能存在 XSS(跨站脚本攻击)风险。
  • 代理服务器:适用于开发环境,方便前端开发人员调试。优点是不需要修改服务器端代码,简单方便;缺点是需要额外配置代理服务器,在生产环境中使用较为复杂。
相关推荐
果冻kk7 分钟前
【宇宙回响】从Canvas到MySQL:飞机大战的全栈交响曲【附演示视频与源码】
java·前端·数据库·spring boot·mysql·音视频·html5
程序媛小盐29 分钟前
Java基础编程练习第34题-正则表达式
java·开发语言·正则表达式
极客先躯31 分钟前
高级java每日一道面试题-2025年3月06日-微服务篇[Eureka篇]-Eureka服务注册与发现是什么?
java·微服务·eureka
少年的范儿33 分钟前
maven在windows系统上的详细安装和配置
java·windows·maven
不如打代码KK37 分钟前
jvm中每个类的Class对象是唯一的吗
java·jvm
vivo互联网技术42 分钟前
缓存监控治理在游戏业务的实践和探索
java·后端·开源
ling__wx1 小时前
List、Set 和 Map 的区别及常见实现类、线程安全集合(总结图表)
java·list·set·map·集合·线程安全
元亓亓亓1 小时前
java后端开发day32--集合进阶(二)ArrayList&LinkedList&泛型&通配符&二叉树
java·数据结构
橘猫云计算机设计1 小时前
基于ssm学科竞赛小程序的设计及实现(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·小程序·毕业设计