- 跨域指:跨域名访问
包括:域名不同
域名相同,端口不同
二级域名不同
不包括:域名端口相同,路径不同 - 起因:
浏览器对于ajax请求的一种限制,一个网站的ajax请求,只能用于同域名的路径,这能有效阻止跨站攻击
跨域问题只针对ajax - 触决方案:三种
jsonp 最早的,利用script标签可以跨域的原理(限制:需要服务支持,只能是get请求)
nginx反向代理:利用反向代理,把跨域变成不跨域(缺点:需要在nginx进行额外配置)
CORS 规范化,安全可靠:在服务端控制,可自定义规则,支持各种请求(缺点:会产生额外请求)
- CORS
是w3c标准,全称是‘跨域资源共享’
它允许浏览器向跨域服务器,发出xmlhttpRequest请求,从而克服了ajax只能同源使用的限制 - cors需要浏览器和服务器同时支持:
浏览器:
目前,所有的浏览器都支持该功能(id10以下不支持),cors通信过程自动完成,不需要参与
服务器:
sors通信和ajax没有任何差别,不需要改变业务逻辑。只不过浏览器会在请求头中携带一些头信息,我们以此判断是否允许跨域,然后在响应头中加入一些信息即可。一般通过过滤器完成 - 原理
浏览器会将ajax请求分为两类,简单请求和复杂请求
简单请求:
请求方法有三种: head get post
http请求头信息包含几种字段 accept accept-Language content-language last-event-ID content_type:(只限三个值)text/plain、application/x-www-form-rulencoded、multipart/form-data
当浏览器发现是简单请求,会在请求头中携带一个字段:origin(Origin:http://localhost:63342)浏览器中可以看到 - Origin中会指出当前请求属于哪个域(协议+域名+端口),服务可以这个值决定是否允许跨域,如果允许,需要在响应头中携带下面的信息
Access.controll-allow-origin:http://localhost:63342(表示服务器可接受的域)
Access.controll-allow-origin:http:true(是否允许携带cookie,默认不携带,除非这个值为true)
跨域请求要想操作cookie,要满足三个条件:1.Access.controll-allow-origin:http:true 2.浏览器发起ajax需要指定withcredentials 为true 3.响应头中的access_control-allow_origin一定不能为*,必须指定域名
特殊请求(繁杂请求):
特殊请求会在正式通信前,增加一次http请求,称为预检请求
浏览器会先询问服务器,当前网页是否在许可范围,以及可以使用的头信息,http动词。只有得到肯定答复,才会正式发送xmlhttpRequest请求,否则报错
和简单比,多两个头:请求方式 额外的头信息
服务器收到预检请求,如果允许,返回响应
同样比简单多返回 请求方式 额外的头信息
如果都符合,就会再次发送真请求 - 在后端配置,允许跨域的访问(注意修改成自己的域名信息)
package com.bs.duosj.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * @author Administrator * @date 2019/7/2 0002 10:40 * @PackageName:leyou * @ClassName: 描述: */ @Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter(){ //添加cors配置信息 CorsConfiguration config = new CorsConfiguration();//开启跨域服务器 通过bean自动注入后,浏览器自动可以识别 //允许的域,不要写*否则cookies就无法使用了 可以写多个 config.addAllowedOrigin("http://localhost:63342"); // config.addAllowedOrigin("*"); //是否发送cookie信息 允许使用cookie config.setAllowCredentials(true); //允许的请求方式 config.addAllowedMethod("OPTIONS"); config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET"); config.addAllowedMethod("PUT"); config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE"); config.addAllowedMethod("PATCH"); //允许的头信息 config.addAllowedHeader("*"); //有效时长,只要在此时间内,再次请求直接通过 config.setMaxAge(3600L); //添加的映射路径,我们拦截的一切请求 UrlBasedCorsConfigurationSource configSource= new UrlBasedCorsConfigurationSource();//配置全局的拦截 configSource.registerCorsConfiguration("/**",config); //返回新的corsfilter return new CorsFilter(configSource); } }
把上面的配置类,注入到spring中管理,就可以生效,这样就可以实现跨域访问