跨域问题
1.哪种情况算跨域
不同域名属于跨域,如: 和,另外 和也属于不同域名。
主域名和子域名(二级域名、三级域名等)跨域,如: 和 跨域。
不同协议属于跨域,如: 和 。
Ip和域名属于跨域,如:123.23.23.12 和 。
2.Cros介绍
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
3.Cors和Jsonp区别
标准来源
jsonp:jquery提供的跨域方式cors:w3c提供的一个跨域标准
请求方式
jsonp:只支持get方式的跨域cors:支持get和post方式的跨域
版本要求
jsonp:支持所有的浏览器(因为所有浏览器都可以使用script标签发送请求)cors:不支持IE10以下的浏览器
4.cros的流程概述
举例 前端页面:域名(127.0.0.1:9000)、发起请求页面url(127.0.0.1:9000/home)后台服务:域名(127.0.0.1:8086)、访问具体方法url(127.0.0.1:8086/homes/swipe) 步骤一:试探请求(option) ajax请求会先发送一个option请求 询问后台是否允许127.0.0.1:9000跨域访问
Request Headers携带的参数:Headers(跨域访问携带的请求头)、Method(跨域访问的请求方式)、origin(要跨域访问的域名)、referer(跨域时的具体url)
Respone Headers返回的信息:Headers(允许携带的请求头)、Methods(允许的请求方式)、Origin(允许跨域访问的域名)
步骤二:如果上一步option请求返回状态码204,则正式请求(get、post、put…)
5.方式一(全局配置):配置SpringBoot
@Configurationpublic class CorsConfig {@Beanpublic CorsFilter corsFilter(){CorsConfiguration corsConfiguration=new CorsConfiguration();//允许携带请求头corsConfiguration.addAllowedHeader("*");//允许所有访问方法 Get、Post...corsConfiguration.addAllowedMethod("*");//xxx.xxx.xxx是要去访问服务器的域名 比如这个服务器是的 然后的异步请求要访问 此时就算跨域 这里的xxx.xxx.xxx就是corsConfiguration.addAllowedOrigin("http://xxx.xxx.xxx");//可以添加多个corsConfiguration.addAllowedOrigin("http://127.0.0.1:9000");//允许携带cookie//注意:如果为true,那么允许的addAllowedOrigin不能为* corsConfiguration.setAllowCredentials(true);UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource=new UrlBasedCorsConfigurationSource();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);return new CorsFilter(urlBasedCorsConfigurationSource);}}
6.方式二(局部配置):在controller上注解
@Controller@RequestMapping("/homes/swipe")@CrossOrigin(allowedHeaders = "*",methods = {RequestMethod.GET,RequestMethod.POST},origins = {"http://xxx.xxx.xxx","http://xxx1.xxx1.xxx1"},allowCredentials = "true")public class Test{}
7.方式三(通过拦截器)
/*** 对跨域提供支持**/@Overrideprotected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));// 跨域时会首先发送一个 option请求,这里我们给 option请求直接返回正常状态if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {httpServletResponse.setStatus(HttpStatus.OK.value());return false;}return super.preHandle(request, response);}