Spring: 在SpringBoot项目中解决前端跨域问题

这里写目录标题

一、什么是跨域问题

跨域问题,也称为跨域资源共享(CORS,Cross-Origin Resource Sharing)问题,主要出现在Web开发中,尤其是当前端代码和后端代码分别部署在不同的域名下时。由于浏览器的同源策略限制,一个域的网页中通过JavaScript发起的跨域请求会被浏览器阻止,除非响应报文包含了正确的CORS相关头部信息。

跨域问题主要涉及到以下几个关键点:

  • 同源与跨源:如果两个页面的协议、域名和端口都相同,则它们是同源的;否则,它们是跨源的。

  • 浏览器限制:浏览器默认会阻止跨源请求,除非后端服务器明确允许这种请求。

  • CORS头部:为了允许跨源请求,后端服务器需要在响应中包含特定的CORS头部,如Access-Control-Allow-Origin。

  • 预检请求:对于某些类型的跨域请求(如带有自定义头部的请求或PUT/DELETE等请求),浏览器会先发送一个OPTIONS请求进行预检,以检查服务器是否允许这种请求。

解决跨域问题的方法有多种,包括但不限于:

  • 使用CORS:在后端服务器上配置CORS策略,允许特定的跨源请求。
  • 使用代理服务器:在前端和后端之间设置一个代理服务器,前端请求发送到代理服务器,再由代理服务器转发到后端服务器。
  • JSONP:一种古老的跨域技术,利用<script>标签没有跨域限制的特性来实现跨域请求。但JSONP只支持GET请求,且存在安全隐患,而且前后端都需要写相应的代码。
  • 设置document.domain:对于主域名相同而子域名不同的情况,可以通过设置document.domain来实现跨域。

在实际开发中,应根据具体需求和场景选择合适的跨域解决方案。

二、浏览器的同源策略

同源策略是浏览器的一个安全功能,它阻止从一个源加载的文档或脚本与另一个源的资源进行交互。这是为了防止恶意文档读取或修改另一个源加载的资源。同源策略限制了不同源之间的DOM访问、AJAX请求以及Web存储访问等。当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。此外浏览器是否启用跨域保护机制是又后端的响应Response来决定的

三、SpringBoot项目中解决跨域问题的5种方式:使用CORS

1、自定 web filter 实现跨域(全局跨域)

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MyCorsFilter implements Filter {
    private static Logger LOGGER = LoggerFactory.getLogger(MyCorsFilter.class);
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "*");

        LOGGER.info("reponse cors: Access-Control-Allow-Origin={}" +
                ", Access-Control-Allow-Methods={}" +
                ", Access-Control-Allow-Credentials={}" +
                ", Access-Control-Allow-Headers={}",
                response.getHeader("Access-Control-Allow-Origin"),
                response.getHeader("Access-Control-Allow-Methods"),
                response.getHeader("Access-Control-Allow-Credentials"),
                response.getHeader("Access-Control-Allow-Headers"));
        chain.doFilter(req, res);
    }
}

2、重写 WebMvcConfigurer(全局跨域)

java 复制代码
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.config.annotation.CorsRegistry;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  
  
@Configuration  
public class WebConfig implements WebMvcConfigurer {  
    @Override  
    public void addCorsMappings(CorsRegistry registry) {  
        registry.addMapping("/**") // 允许所有路径  
                .allowedOrigins("http://example.com") // 允许哪些源的请求  
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法  
                .allowedHeaders("*") // 允许的头部  
                .allowCredentials(true) // 是否允许发送cookies  
                .maxAge(168000); // 预检请求的缓存时间(秒)  
    }  
}

3、 CorsFilter(全局跨域)

CorsFilter 是 Java Spring 框架中用于处理跨域请求(CORS,Cross-Origin Resource Sharing)的过滤器。通过使用 CorsFilter,你可以配置你的 Spring 应用以允许跨域请求,从而避免浏览器因同源策略而阻止这些请求。下面是一个简单的 Spring Boot 应用中如何使用 CorsFilter 的例子:

  • 添加依赖(如果你使用 Spring Boot,这个依赖可能已经包含在内):
java 复制代码
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
</dependency>
  • 创建 CorsFilter:
java 复制代码
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.setAllowedOrigins(Arrays.asList("*")); // 允许所有源进行访问  
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); // 允许的方法  
        config.setAllowCredentials(true); // 是否发送cookie  
        config.setMaxAge(168000); // 预检间隔时间  
  
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        source.registerCorsConfiguration("/**", config); // 对所有路径应用 CORS 配置  
  
        return new CorsFilter(source);  
    }  
}

在这个例子中,我们创建了一个 CorsFilter Bean,它允许来自任何源的请求,并允许 GET、POST、PUT 和 DELETE 方法。我们还设置了 AllowCredentials 为 true,这意味着浏览器可以发送带有凭据(如 cookies、HTTP 认证及客户端 SSL 证明等)的请求。最后,我们设置了 CORS 预检请求的缓存时间为 168000 秒(即 2 天)。

  • 启动你的 Spring Boot 应用。现在,你的应用应该能够处理跨域请求了。请注意,出于安全考虑,你不应该在生产环境中将 AllowedOrigins 设置为 *,除非你完全信任所有可能的源。通常,你会将 AllowedOrigins 设置为一个特定的域名列表。

4、使用@CrossOrigin注解 (局部跨域)

@CrossOrigin 是 Spring Framework 提供的一个注解,用于解决跨域资源共享(CORS)问题。通过在类或者方法上使用 @CrossOrigin 注解,你可以轻松地为 Spring MVC 控制器开启 CORS 支持。这个注解允许你指定哪些域、HTTP 方法以及头部可以被允许进行跨域请求。

  • 在控制器类上使用
    可以直接在控制器类上使用 @CrossOrigin 注解,以允许整个控制器的所有方法都接受跨域请求:
java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
@CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})  
public class MyController {  
    // ... 控制器方法 ...  
}
  • 在单个方法上使用
    可以将 @CrossOrigin 注解添加到特定的控制器方法上,以仅允许该方法的跨域请求:
java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
public class MyController {  
  
    @GetMapping("/someMethod")  
    @CrossOrigin(origins = "http://example.com")  
    public String someMethod() {  
        // ... 方法实现 ...  
        return "Response";  
    }  
}

使用 @CrossOrigin 注解时,你可以指定多个允许的源,方法,头部等。这提供了一种灵活的方式来控制哪些跨域请求应该被允许。需要注意的是,出于安全考虑,你应该仔细考虑允许哪些源进行跨域请求,并限制允许的 HTTP 方法和头部。

最后,确保你的 Spring Boot 应用已经包含了 Spring Web 的依赖,并且你的控制器类和方法已经正确地映射到了相应的 URL 路径。这样,当来自允许源的请求到达时,Spring MVC 就会自动处理 CORS 预检请求,并在响应中包含正确的 CORS 头部。

相关推荐
web Rookie9 分钟前
React 中 createContext 和 useContext 的深度应用与优化实战
前端·javascript·react.js
男孩1213 分钟前
react高阶组件及hooks
前端·javascript·react.js
m0_7482517234 分钟前
DataOps驱动数据集成创新:Apache DolphinScheduler & SeaTunnel on Amazon Web Services
前端·apache
珊珊来吃34 分钟前
EXCEL中给某一列数据加上双引号
java·前端·excel
herogus丶1 小时前
【Spring AI】Spring AI Alibaba的简单使用
java·人工智能·spring·ai
onejason1 小时前
深度解析:利用Python爬虫获取亚马逊商品详情
前端·python
胡西风_foxww1 小时前
【ES6复习笔记】Spread 扩展运算符(8)
前端·笔记·es6·扩展·运算符·spread
小林爱1 小时前
【Compose multiplatform教程08】【组件】Text组件
android·java·前端·ui·前端框架·kotlin·android studio
跨境商城搭建开发2 小时前
一个服务器可以搭建几个网站?搭建一个网站的流程介绍
运维·服务器·前端·vue.js·mysql·npm·php
hhzz2 小时前
vue前端项目中实现电子签名功能(附完整源码)
前端·javascript·vue.js