跨域在网上帖子很多很多,不过太多太杂加之前端问题本身比较繁琐,所以实际不一定那么管用,本文也仅仅是列举出来几种具体实现方法。
首先,跨域要么从前端解决,要么从后端解决.
spring提供跨域注解,我们只需要将跨域注解写在控制层的类上,或者方法上就可以实现跨域请求。
@Controller
@CrossOrigin
public class UserController {
}
这种方式最为简单,我们也可以指定跨域的一些具体属性,就不作解释了。
@Component
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("来到了拦截器...");
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "0");
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("XDomainRequestAllowed","1");
return true;
}
}
配置拦截规则:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Autowired
RequestInterceptor requestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截所有请求
registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
@Configuration
public class MyConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Ajax默认提供跨域属性:crossDomain: true,设置为true表示允许跨域,搭配如下属性,
xhrFields: {
withCredentials: true
},
crossDomain: true,
表示在请求的时候会携带凭证信息,即cookie信息,这样就可以保证我们实现同步会话的功能,比如在登录功能的实现。
完整方法:
function getGongyiList() {
var list;
$.ajax({
url: gongyiListUrl,
async: false,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function(data) {
list = data
console.log(list)
},
error: function(data) {
alert("获取订单列表失败!")
}
})
return list;
}
对于Ajax请求来说,请求是XMLHTTPRequest
对象发起的而不是浏览器,所以如果不加上述属性,每次请求都会去生成一个新的SessionId,无法保证session为同一个,加上withCredentials属性以后,它就会携带cookie信息去请求,不用每次取创建新的会话。
其他跨域方式还有jsonp,nginx代理等方式,有兴趣可以研究下。