• application/json 请求跨域无法携带cookie问题


    前后端分离的项目中,一般前端会有一个域名,后端接口会有一个域名。如果后端接口生成的cookie,前端请求时,cookie无法携带上来

    因此前端需要配置withCredentials属性,CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。

    前端配置

    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;

    需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

    服务端配置(spring-mvc为例)

    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

    如果是x-www-form-urlencoded请求时,只会发一个请求,并且会把cookie携带上来,请求如下:

    但如果是application/json请求时,则会发送两个请求,第一个为“预检”请求,类型为options。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    而这个“预检”请求中,是不会携带cookie的,因此服务端如果没有做特殊处理,就会去检查“预检”请求中的cookie,如果发现没有,则直接提示未登录,这样就有问题了。

    解决方法可以是在检查代码中,遇到OPTIONS请求,先放行,然后再第二次正式的post请求中,则再去对用户鉴权。

    if("OPTIONS".equals(request.getMethod())){
        return true;
    }

    下面是“预检”请求和正式请求:

     

    具体的原理可以参考下面的文章,已经说的很清楚了

    http://www.ruanyifeng.com/blog/2016/04/cors.html

    
    
  • 相关阅读:
    MongoDB优化之一:常见优化方法
    Spark Streaming之一:整体介绍
    Java中实现MongoDB自增主键ID
    RDD之一:总体介绍
    对一致性Hash算法,Java代码实现的深入研究
    MongoDB 创建基础索引、组合索引、唯一索引以及优化
    mongo-查询
    MongoTemplate聚合操作
    RESTLET开发实例(一)基于JAX-RS的REST服务
    Hashtable的实现原理
  • 原文地址:https://www.cnblogs.com/kangjianrong/p/9725068.html
Copyright © 2020-2023  润新知