跨域解决以及重定向
前言
博主github
博主个人博客http://blog.healerjean.com
1、跨域的一般解决方式
1.1、配置拦截器
1.1.1、token在healer传递的时候,一定要这里配置
@Component
@Slf4j
public class CORSInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//添加跨域CORS
// 服务器不在一起,下面这个跨域是马川 给我的,好用
String originHeader = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", originHeader);
response.addHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,accessToken");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
return true;
}
}
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter{
@Autowired //解决跨域
private CORSInterceptor corsInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(corsInterceptor);
super.addInterceptors(registry);
}
}
2、解释名词
2.1、什么是跨域
请求从一个域发送到了另一个域
// 跨域请求例子
https://localhost:8080/api/user
https://localhost:8081/
跨域错误
No 'Access-Control-Allow-Origin' header is present on the requested resource
当某一条请求通过浏览器发出,浏览器会在请求头部加上该请求来自的域(origin),请求的接收方去判断他是否愿意处理来自这个域的请求,如果愿意就在请求头部加上Access-Control-Allow-Origin:origin
,请求回来后,浏览器再去检查这个头部是否包含这个值Access-Control-Allow-Origin ,如果没有就会爆出以上的错误
2.2、简单请求和非简单请求
2.2.1、简单请求
具体是指请求方法是简单方法
且请求头是简单头
的 HTTP 请求。具体地,
- 简单方法包括
GET
,HEAD
,POST
。 - 简单头不超过以下几个字段:
-
Accept
,Accept-Language
,Content-Language
,Content-Type
为application/x-www-form-urlencoded
,multipart/form-data
,text/plain
举个例子:
GET /test HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, sdch, br
Origin: http://www.examples.com
Host: www.examples.com
对于简单请求,CORS
的策略是请求时在请求头中增加一个Origin
字段,服务器收到请求后,根据该字段判断是否允许该请求访问。
解决方案
1. 如果允许,则在 HTTP 头信息中添加 `Access-Control-Allow-Origin` 字段,并返回正确的结果 ;
2. 如果不 允许,则不在 HTTP 头信息中添加 `Access-Control-Allow-Origin` 字段
2.2.2、非简单请求(会引起跨域问题)
对于非简单请求的跨源请求,浏览器会在真实请求发出前,增加一次OPTION
请求,称为预检请求(preflight request
)。预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到 HTTP 头信息字段中,询问服务器是否允许这样的操作。
-
put
,delete
方法的ajax请求 -
发送
json
格式的ajax请求 -
带自定义头的ajax请求
举个例子:
OPTIONS /test HTTP/1.1
Origin: http://www.examples.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: X-Custom-Header
Host: www.examples.com
与 CORS
相关的字段有:
- 请求使用的
HTTP
方法Access-Control-Request-Method
; - 请求中包含的自定义头字段
Access-Control-Request-Headers
。
服务器收到请求时,需要分别对 Origin
、Access-Control-Request-Method
、Access-Control-Request-Headers
进行验证,验证通过后,会在返回 HTTP
头信息中添加 :
解决方案 :
Access-Control-Allow-Origin: http://www.examples.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
2.3、跨域配置
Access-Control-Allow-Origin: 服务器允许的域名 这里只能设置一个域名,不能设置多个,或者设置为 *
Access-Control-Allow-Methods: 真实请求允许的方法
Access-Control-Allow-Headers: 服务器允许使用的字段
Access-Control-Allow-Credentials: 是否允许用户发送、处理 cookie
Access-Control-Max-Age: 预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
2.4、跨域重定向
也就是按照我们正常的逻辑走就行了,就是看请求origin的和返回的origin是不是同一个,非简单的请求的preflight如果没有通过,则不会重定向
- 对于简单请求并且没有任何 preflight 的情况:浏览器会一直跟随重定向(当然 HTTP 另有规定的除外,如 POST 被 302 时),直到最后一个请求返回或者中间请求的 CORS 验证失败(比如Access-Control-Allow-Origin设置错误)。
- 对于简单请求但是浏览器会发起 preflight 的情况(比如 Safari 对 DNT 的处理):因 preflight 后重定向真正的请求会导致 CORS 失败,所以多次重定向是不可行的。
- 对于非简单请求:浏览器会直接发起 preflight,后续的重定向都是不允许的因此多次重定向不可行。
感兴趣的,欢迎添加博主微信
哈,博主很乐意和各路好友交流,如果满意,请打赏博主任意金额,感兴趣的在微信转账的时候,备注您的微信或者其他联系方式。添加博主微信哦。
请下方留言吧。可与博主自由讨论哦
微信 | 微信公众号 | 支付宝 |
---|---|---|