51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

SpringBoot 如何解决跨域问题?

嗨,你好呀,我是猿java

跨域问题是Web开发中常见的问题之一,特别是在前后端分离的项目中。Spring Boot作为一个流行的Java后端框架,提供了多种方式来解决跨域问题。本文将深入探讨Spring Boot如何解决跨域问题,包括原理分析、代码实现和示例展示。

跨域问题 {#跨域问题}

什么是跨域 {#什么是跨域}

跨域是指浏览器出于安全考虑,对来自不同域名、协议或端口的请求进行限制。通常,当一个网页发起的请求目标是与其来源不同的域时,就会发生跨域问题。浏览器采用同源策略(Same-Origin Policy)来阻止某些不安全的请求。

同源策略 {#同源策略}

同源策略是浏览器的一个安全特性,用于防止恶意网站读取另一个网站的敏感信息。只有当协议、域名和端口号都相同时,浏览器才允许请求通过。

CORS {#CORS}

CORS,全称 Cross-Origin Resource Sharing 翻译为跨域资源共享,它使用额外的 HTTP头来告诉浏览器允许 Web应用从不同的域进行请求。CORS是 W3C的一个标准,允许服务器声明哪些源站点可以访问它的资源。

Spring Boot如何解决跨域? {#Spring-Boot如何解决跨域?}

整理来说,Spring Boot解决跨域问题的方法有三种:

  1. 全局配置CORS
  2. 使用@CrossOrigin注解
  3. 自定义过滤器

全局配置CORS {#全局配置CORS}

在Spring Boot中,可以通过实现WebMvcConfigurer接口来全局配置CORS。

|------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import org.springframework.context.annotation.Bean; 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") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } } |

代码分析

  • addMapping("/**"): 允许所有路径的请求。
  • allowedOrigins("http://example.com"): 允许的跨域请求来源。
  • allowedMethods("GET", "POST", "PUT", "DELETE"): 允许的HTTP方法。
  • allowedHeaders("*"): 允许的请求头。
  • allowCredentials(true): 是否允许发送Cookie。
  • maxAge(3600): 预检请求的缓存时间。

使用@CrossOrigin注解 {#使用-CrossOrigin注解}

Spring提供了@CrossOrigin注解用于简化跨域配置。可以在控制器类或方法级别使用。

|---------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 { @CrossOrigin(origins = "http://example.com") @GetMapping("/greet") public String greet() { return "Hello World"; } } |

代码分析

  • @CrossOrigin(origins = "http://example.com"): 指定允许跨域的来源。
  • 可以在类级别使用@CrossOrigin,应用于该类的所有请求方法。

自定义过滤器 {#自定义过滤器}

通过自定义过滤器,可以更灵活地处理跨域请求。

如下示例代码,自定义过滤器 CorsFilter 实现 Filter,从而允许https://yuanjava.com 作为跨域的来源。

|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import org.springframework.stereotype.Component; @Component public class CorsFilter implements CorsFilter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; res.setHeader("Access-Control-Allow-Origin", "https://yuanjava.com"); res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); res.setHeader("Access-Control-Allow-Headers", "Content-Type"); res.setHeader("Access-Control-Allow-Credentials", "true"); if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) { res.setStatus(HttpServletResponse.SC_OK); return; } chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } } |

代码分析:

  • setHeader("Access-Control-Allow-Origin", "https://yuanjava.com"): 设置允许跨域的来源。
  • setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"): 设置允许的HTTP方法。
  • setHeader("Access-Control-Allow-Headers", "Content-Type"): 设置允许的请求头。
  • setHeader("Access-Control-Allow-Credentials", "true"): 允许发送Cookie。
  • 对于OPTIONS预检请求,直接返回状态码200。

示例展示 {#示例展示}

假设我们有一个简单的 Spring Boot应用程序,它提供一个 RESTful API。我们希望允许来自"https://yuanjava.com"的跨域请求。

项目结构 {#项目结构}

|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 | src └── main ├── java │ └── com │ └── yuanjava │ ├── CorsFilter.java │ ├── MyController.java │ └── WebConfig.java └── resources └── application.properties |

代码实现 {#代码实现}

  • WebConfig.java: 全局配置CORS
  • MyController.java: 使用@CrossOrigin注解
  • CorsFilter.java: 自定义过滤器

测试跨域请求 {#测试跨域请求}

可以使用Postman或编写简单的JavaScript代码来测试跨域请求。

|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 | fetch('http://localhost:8080/greet', { method: 'GET', headers: { 'Content-Type': 'application/json' }, credentials: 'include' }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); |

验证 {#验证}

  • 启动Spring Boot应用程序。
  • 通过浏览器或Postman测试API。
  • 确认跨域请求成功,并在控制台或日志中查看请求和响应。

总结 {#总结}

通过本文,我们详细探讨了 Spring Boot解决跨域问题的三种方法,包括全局配置、使用注解和自定义过滤器。每种方法都有其优缺点,选择哪种方式取决于应用的具体需求和复杂性。

  • 全局配置: 适用于需要统一配置跨域策略的应用。
  • @CrossOrigin注解: 适合于特定控制器或方法的跨域配置。
  • 自定义过滤器: 提供更灵活的跨域处理方式。

交流学习 {#交流学习}

最后,把猿哥的座右铭送给你:投资自己才是最大的财富。 如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注公众号:猿java,持续输出硬核文章。

赞(4)
未经允许不得转载:工具盒子 » SpringBoot 如何解决跨域问题?