跨域解决以及重定向

前言

博主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-Typeapplication/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 头信息字段中,询问服务器是否允许这样的操作。

  • putdelete方法的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 相关的字段有:

  1. 请求使用的 HTTP 方法 Access-Control-Request-Method
  2. 请求中包含的自定义头字段 Access-Control-Request-Headers

服务器收到请求时,需要分别对 OriginAccess-Control-Request-MethodAccess-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,后续的重定向都是不允许的因此多次重定向不可行。


感兴趣的,欢迎添加博主微信

哈,博主很乐意和各路好友交流,如果满意,请打赏博主任意金额,感兴趣的在微信转账的时候,备注您的微信或者其他联系方式。添加博主微信哦。

请下方留言吧。可与博主自由讨论哦

微信 微信公众号 支付宝
微信 微信公众号 支付宝
posted @ 2019-05-23 12:25  HealerJean  阅读(1651)  评论(0编辑  收藏  举报