springboot 前后端分离开发解决跨域访问

时间:2023-03-09 12:55:24
springboot 前后端分离开发解决跨域访问

  最近新学习了Java EE开发框架springboot,我在使用springboot前后台分离开发的过程中遇到了跨域求问题。在网上寻找答案的过程中发现网上的解决方案大多比较零散,我在这里整理一个解决方案,但未必是最好的方案。

  要在项目中解决跨域访问,需要解决三个问题:

  1. 服务器需要接受不同域的浏览器的请求
  2. 浏览器允许读取不同域的服务器的响应数据
  3. 保证浏览器每次访问的session是一致的

  第一个问题,服务器接受不同域的浏览器的请求,这是后台开发人员需要解决的问题。具体的解决方案有几种,我这里只总结了在springboot中使用cors协议的解决方案。其实即使是springboot中cors协议解决方案也分几种不同的解决方法,下面有一种的代码,就是生成一个org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口的实例对象,并且将它纳入到spring容器中。这是一个全局的方法,比较方便,当然可以为局部请求设置允许跨域访问,这里不介绍。

示例代码:

import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CreateBean { @Bean
public WebMvcConfigurer corsConfigurer(){
WebMvcConfigurer configurer = new WebMvcConfigurer(){ @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://127.0.0.1:8020")
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
.allowCredentials(true).maxAge(3600);
} };
return configurer;
}
}

代码中的registry.addMapping("/**")表示所有的请求路径都可以跨域访问。allowedOrigins("http://xxx.com:xx")代表接收的请求的原服务器地址,这个方法的参数是可变参数,可以设置多个源服务器,如果允许所有,可以使用“*”代替(但是不推荐这么写)。

  解决第一个问题,那么服务器这关就通过了。但是B/S架构的web应用除了服务器,还有浏览器。在浏览器中有一个同源访问策略(火狐和谷歌都有,不知道其他的浏览器有没有),这里策略有可能禁止读取跨域访问的响应数据。其实在springboot中解决这个问题还是很简单的,只需要设置allowedOrigins()为具体的服务器地址,也就是不使用“*”代替,然后设置allowCredentials(true)就可以了

  第三个问题,解决session问题。在跨域请求中,每次请求传递给服务器的sessionid是不同的,这就造成了在服务器每次都给浏览器创建一个session,所以服务器不能获取session中存放的数据,为了解决这个问题,使用jQuery的解决访问时在options参数中添加字段xhrFields:{withCredentials:true}:

    $.ajax({
method:"post",
url:basePath+"user/login",
data:{
username:login.username,
password:login.password,
validateCode:login.validatecode
},
xhrFields:{
withCredentials:true
},
success:function(res){
console.log(res)
alert(res.message)
},
error:function(error){
alert(error)
console.log(error)
}
})