咱们有不少种方式解决跨域请求
本篇为你们讲解使用CORS解决跨域html
CORS又称跨域资源共享
它须要浏览器和服务器的同时支持
在开发过程当中,浏览器并不会有过多的变化
服务器是关键,只有服务器实现了CORS接口,才能够进行跨域请求前端
CORS对于浏览器发过来的AJAX跨域请求分为两种:
简单请求和非简单请求java
所谓简单请求就是HEAD,GET,POST三种请求方式
浏览器会在在header信息里面多加一个字段:
key:origin
value:协议+域名+端口(如https://localhost:8080)ajax
服务器根据对象里的origin值来决定是否赞成此次请求spring
若是请求经过
请求经过后,服务器会在header里多增长几个字段:json
Access-Control-Allow-Origin: https://localhost:8080 Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: Token
解释:
1.Credentials是否容许包含cookie,若是返回了true,那么浏览器发送请求体的时候要添加:后端
var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
如此这般,才能向服务器发送cookie跨域
2.Access-Control-Expose-Headers是多返回的字段名,根据实际需求改变浏览器
若是请求失败
说明以前发送Origin的value不在许可范围内
服务器会返回一个正常的HTTP回应
浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段
从而抛出一个没法跨域的异常(多是200,因此没法识别)缓存
简单请求的方法是Head,Get,Post
那么非简单请求的方法就是Put,Delete,或者Content-Type是application/json
非简单请求在发出CORS请求以前,会增长一次HTTP查询请求,也叫预检请求
预检请求成功了,浏览器才能发出XMLHttpRequest,不然报错
若是浏览器发现这是一个非简单请求
就会先发送一个预检请求:
OPTIONS /cors HTTP/1.1 Origin: http://localhost:8088 Access-Control-Request-Method: PUT Access-Control-Request-Headers: token
预测请求的方法名叫OPTIONS
Origin和简单请求同样
Access-Control-Request-Method是请求方法
Access-Control-Request-Headers是额外发送的头信息字段
(tip:预检请求通常缓存下来,以便不须要在每次请求都发送)
若是预检请求经过
咱们来看下服务器发出的回应
HTTP/1.1 200 OK Date: Nov, 01 Dec 2017 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://localhost:8088 Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: token Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
若是预检请求失败
服务器会返回一个HTTP回应(没有CORS的头信息字段)
并在console打出not allowed by Access-Control-Allow-Origin
异常
预检请求经过之后
浏览器发每次出的CORS请求就和简单请求同样
会有一个origin字段
服务器每次回应都会有Access-Control-Allow-Origin
头信息字段
前端jQuery写法:
$.ajax({ type: "POST", url: baseUrl + "/post", dataType: 'json', crossDomain: true, xhrFields: { withCredentials: true }, data: { name: "name_from_frontend" }, success: function (response) { console.log(response)// 返回的 json 数据 $("#response").val(JSON.stringify(response)); } });
crossDomain: true是指开启跨域
后端mvc配置类:
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**/*").allowedOrigins("*"); } }
这是spring4.2以上版本
若是是4.2如下的:
public class CrossDomainFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.addHeader("Access-Control-Allow-Origin", "*");// 若是提示 * 不行,请往下看 response.addHeader("Access-Control-Allow-Credentials", "true"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); filterChain.doFilter(request, response); } }
4.2如下还需加过滤器:
<filter> <filter-name>CrossDomainFilter</filter-name> <filter-class>com.javadoop.filters.CrossDomainFilter</filter-class> </filter> <filter-mapping> <filter-name>CrossDomainFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
以上即是CORS请求的原理;
以为还能够的请点个赞,赞不了也能够收藏下;
总之,谢谢阅读~