模板网站seo,ide 在线 wordpress,wordpress 页面插件,东莞注册公司需要什么资料文章目录 一、跨域介绍1、什么是跨域2、为什么会产生跨域 二、简单请求和非简单请求1、简单请求2、非简单请求2.1、预检请求2.2、预检请求的回应2.3、浏览器的正常请求和回应 三、CrossOrigin注解1、CrossOrigin源码2、CorsRegistry方式3、CorsFilter过滤器4、自定义过滤器 一、… 文章目录 一、跨域介绍1、什么是跨域2、为什么会产生跨域 二、简单请求和非简单请求1、简单请求2、非简单请求2.1、预检请求2.2、预检请求的回应2.3、浏览器的正常请求和回应 三、CrossOrigin注解1、CrossOrigin源码2、CorsRegistry方式3、CorsFilter过滤器4、自定义过滤器 一、跨域介绍
1、什么是跨域
同源策略Sameoriginpolicy是浏览器最核心也最基本的安全功能一个页面发起的ajax请求只能是与当前页域名相同的路径这能有效的阻止跨站攻击所谓同源即指在同一个域就是两个页面具有相同的协议protocol主机host和端口号
2、为什么会产生跨域
前后端分离模式下,客户端请求前端服务器获取视图资源客户端向后端服务器获取数据资源前端服务器的协议,IP和端口和后端服务器不一样就产生了跨域 二、简单请求和非简单请求
CORS是一个W3C标准全称是跨域资源共享Cross-origin resource sharing它允许浏览器向跨源服务器发出XMLHttpRequest请求从而克服了AJAX只能同源使用的限制浏览器将CORS请求分成两类简单请求simple request和非简单请求not-so-simple request
1、简单请求 只要同时满足以下两大条件就属于简单请求 请求方法是以下三种方法之一 HEADGETPOST HTTP的头信息不超出以下几种字段 AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type只限制三个值 application/x-www-form-urlencodedmultipart/form-datatext/plain 基本流程 对于简单请求浏览器直接发出CORS请求。具体来说就是在头信息之中增加一个Origin字段 举例 浏览器发现这次跨源AJAX请求是简单请求就自动在头信息之中添加一个Origin字段Origin字段用来说明本次请求来自哪个源协议 域名 端口。服务器根据这个值决定是否同意这次请求
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...如果Origin指定的源不在许可范围内服务器会返回一个正常的HTTP回应 浏览器发现这个回应的头信息没有包含Access-Control-Allow-Origin字段详见下文从而抛出一个错误但是这种错误无法通过状态码识别因为HTTP回应的状态码有可能是200 如果Origin指定的域名在许可范围内服务器返回的响应会多出几个头信息字段
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charsetutf-8上面的头信息之中有三个与CORS请求相关的字段都以Access-Control-开头
Access-Control-Allow-Origin 该字段是必须的要么是请求时Origin字段的值要么是一个*表示接受任意域名的请求 Access-Control-Allow-Credentials 该字段可选它的值是一个布尔值表示是否允许发送Cookie默认情况下Cookie不包括在CORS请求之中设为true即表示服务器明确许可Cookie可以包含在请求中一起发给服务器注意如果要发送CookieAccess-Control-Allow-Origin就不能设为星号必须指定明确的、与请求网页一致的域名 Access-Control-Expose-Headers 该字段可选CORS请求时XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma如果想拿到其他字段就必须在Access-Control-Expose-Headers里面指定上面的例子指定可以返回FooBar字段的值
2、非简单请求
2.1、预检请求
非简单请求是那种对服务器有特殊要求的请求 比如请求方法是PUT或DELETE或者Content-Type字段的类型是application/json 非简单请求的CORS请求会在正式通信之前增加一次HTTP查询请求称为预检请求 浏览器先询问服务器当前网页所在的域名是否在服务器的许可名单之中以及可以使用哪些HTTP动词和头信息字段只有得到肯定答复浏览器才会发出正式的请求否则就报错 举例 HTTP请求的方法是PUT并且发送一个自定义头信息X-Custom-Header下面是这个预检请求的HTTP头信息
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...预检请求用的请求方法是OPTIONS表示这个请求是用来询问的。头信息里面关键字段是Origin表示请求来自哪个源Access-Control-Request-Method 该字段是必须的用来列出浏览器的CORS请求会用到哪些HTTP方法 Access-Control-Request-Headers 该字段是一个逗号分隔的字符串指定浏览器CORS请求会额外发送的头信息字段
2.2、预检请求的回应
服务器收到预检请求以后检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后确认允许跨源请求就可以做出回应
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charsetutf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout2, max100
Connection: Keep-Alive
Content-Type: text/plain关键的是Access-Control-Allow-Origin字段 表示http://api.bob.com可以请求数据该字段也可以设为星号表示同意任意跨源请求 Access-Control-Allow-Methods 该字段必需它的值是逗号分隔的一个字符串表明服务器支持的所有跨域请求的方法注意返回的是所有支持的方法而不单是浏览器请求的那个方法。这是为了避免多次预检请求 Access-Control-Allow-Credentials 该字段与简单请求时的含义相同 Access-Control-Max-Age 该字段可选用来指定本次预检请求的有效期单位为秒上面结果中有效期是20天1728000秒在此期间不用发出另一条预检请求 如果服务器否定了预检请求会返回一个正常的HTTP回应但是没有任何CORS相关的头信息字段浏览器就会认定服务器不同意预检请求控制台会打印出如下的报错信息
XMLHttpRequest cannot load http://api.alice.com. Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
2.3、浏览器的正常请求和回应
一旦服务器通过了预检请求以后每次浏览器正常的CORS请求就都跟简单请求一样会有一个Origin头信息字段服务器的回应也都会有一个Access-Control-Allow-Origin头信息字段 预检请求之后浏览器的正常CORS请求 头信息的Origin字段是浏览器自动添加的
PUT /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...服务器正常的回应 Access-Control-Allow-Origin字段是每次回应都必定包含的
Access-Control-Allow-Origin: http://api.bob.com
Content-Type: text/html; charsetutf-8三、CrossOrigin注解
1、CrossOrigin源码
CrossOrigin可以用在被RequestMapping修饰的方法和Controller类上添加此注解即可实现跨域请求
Target({ElementType.TYPE, ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
Documented
public interface CrossOrigin {AliasFor(origins)String[] value() default {};AliasFor(value)String[] origins() default {};/*** since 5.3*/String[] originPatterns() default {};String[] allowedHeaders() default {};String[] exposedHeaders() default {};RequestMethod[] methods() default {};String allowCredentials() default ;long maxAge() default -1;
}CrossOrigin属性介绍 origins和value 支持的源origins和value都是相同的配置互为别名默认配置是“*”表示服务器支持所有源的跨域请求安全信息较低最好根据实际情况设置对应的信息协议 域名 端口 originPatterns 同样表示支持的源Spring 5.3 引入的属性默认为空与origins二选一该字段为list也就是可以配置多个 allowedHeaders 允许跨域的请求头信息默认为“*”表示允许所有的请求头CORS默认支持的请求头为Cache-Control、Content-Language、Expires、Last-Modified、Pragma如果你需要携带其他的请求头需要设置该属性 exposedHeaders 服务器允许客户端访问的相应头默认为空表示只允许访问Cache-Control、Content-Language、Expires、Last-Modified、Pragm如果需要客户端访问其他的相应头需要设置该属性 methods 服务器允许的Http Request类型默认是允许GET、POST、HEAD allowCredentials 浏览器是否需要把凭证如cookies、CSRF tokens发送到服务器默认是关闭的该选项开启后会与配置的源建立高度信任的关系并且还会暴露一些敏感信息所以开启该选项时origin不允许设置为“*” maxAge “预检”结果的缓存时间单位是秒默认1800s在缓存时间内同一请求不需要“预检”请求
CrossOrigin注解比较适用于较细粒度的跨域控制
2、CorsRegistry方式
Configuration
//创建WebConfig类实现WebMvcConfigurer接口通过CorsRegistry设置跨域信息
public class WebConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/api/**).allowedOrigins(https://domain2.com).allowedMethods(PUT, DELETE).allowedHeaders(header1, header2, header3).exposedHeaders(header1, header2).allowCredentials(true).maxAge(3600);}
}3、CorsFilter过滤器
在跨域过滤器里配置一下跨域头部* 是通配符即允许所有
Configuration
public class GatewayCorsConfiguation {Beanpublic CorsFilter corsFilter(){// 初始化cors配置对象CorsConfiguration configuration new CorsConfiguration();// 允许使用cookie但是使用cookie是addAllowedOrigin必须是具体的地址不能是*configuration.setAllowCredentials(true);
// configuration.addAllowedOrigin(*);configuration.addAllowedOrigin(http://manage.leyou.com);//允许的请求方式,get,put,post,deleteconfiguration.addAllowedMethod(*); //允许的头信息configuration.addAllowedHeader(*);//初始化cors的源对象配置UrlBasedCorsConfigurationSource corsConfigurationSource new UrlBasedCorsConfigurationSource();corsConfigurationSource.registerCorsConfiguration(/**,configuration);//返回新的CorsFilter.return new CorsFilter(corsConfigurationSource);}
}
4、自定义过滤器
WebFilter(/*)
public class CrosFilter implements Filter {Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response (HttpServletResponse) servletResponse;HttpServletRequest request (HttpServletRequest) servletRequest;response.setHeader(Access-Control-Allow-Origin, *);response.setHeader(Access-Control-Allow-Methods, POST, GET, OPTIONS, DELETE, HEAD);response.setHeader(Access-Control-Max-Age, 3600);response.setHeader(Access-Control-Allow-Headers, access-control-allow-origin, authority, content-type, version-info, X-Requested-With);// 非预检请求,放行即可,预检请求,则到此结束,不需要放行if(!request.getMethod().equalsIgnoreCase(OPTIONS)){filterChain.doFilter(servletRequest, servletResponse);}}
}