Java 后端解决跨域问题

之前项目中遇到过前端跨域问题,特此记录便于日后查阅。

前端跨域问题解决方式有很多种,其中一种就是在页面请求的目标服务配置跨域代码,因为我们的项目是前后端分离的,后端统一要通过路由网关来进行请求转发,所以我只需要在路由网关服务配置跨域代码即可,代码如下:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableZuulProxy
public class ZuulApplication {

	public static void main(String[] args) {
		SpringApplication.run(ZuulApplication.class, args);
	}

	/**
	 * attention:简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain
	 * 反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求
	 */
	@Bean
	public CorsFilter corsFilter() {
		final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		final CorsConfiguration confi
### JAVA后端问题解决方案 #### 方法一:实现 `WebMvcConfigurer` 接口 可以通过自定义配置类并实现 `WebMvcConfigurer` 接口的方式,在全局范围内设置允许的请求参数。这种方式适用于大多数场景下的需求。 ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 允许所有的接口路径被访问 .allowedOrigins("http://localhost:3000") // 设置允许的前端.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法 .allowedHeaders("*") // 允许的头部信息 .allowCredentials(true); // 是否支持携带Cookie } } ``` 这种方法简单易用,适合中小型项目的快速部署[^1]。 --- #### 方法二:使用 `@CrossOrigin` 注解 对于特定的控制器或方法,可以直接在其上添加 `@CrossOrigin` 注解来指定允许的规则。此方式灵活性较高,可以针对单个接口进行细粒度控制。 ```java @RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true", allowedHeaders = "*") public class ExampleController { @GetMapping("/data") public String getData() { return "This is cross-origin data"; } } ``` 该方案特别适合于某些特殊接口需要独立处理的情况[^2]。 --- #### 方法三:通过拦截器 (`HandlerInterceptor`) 实现 利用拦截器可以在请求到达具体业务逻辑之前对其进行预处理,从而动态地调整响应头中的相关内容。 ```java @Component public class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return false; } return true; } } ``` 这种做法能够更灵活地应对复杂的场景,尤其是在需要根据不同条件动态修改响应头的情况下非常有用[^3]。 --- #### 方法四:使用过滤器 (Filter) 创建一个基于 Servlet 的过滤器,统一为所有请求添加必要的响应头。 ```java @Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } } ``` 相比其他方式,过滤器的优势在于它可以完全脱离框架而工作,因此更加通用和稳定[^4]。 --- #### 方法五:Spring Security 中启用 CORS 支持 如果项目中集成了 Spring Security,则需要显式开启对 CORS 请求的支持,否则即使设置了规则也可能无法正常生效。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() .csrf().disable(); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } } ``` 这是生产环境中推荐的做法之一,因为它能更好地与其他安全性功能协同运作[^4]。 --- #### 总结 每种方法都有其适用范围和优缺点,实际应用时应根据具体的项目架构和技术栈选择最合适的方案。例如,小型项目可以选择简单的注解形式;而对于大型复杂系统则可能更适合采用集中式的配置管理手段如过滤器或者集成到安全框架之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地表最强菜鸡

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值