zoukankan      html  css  js  c++  java
  • 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

    
    
  • 相关阅读:
    javascript循环结构练习
    个人复习JavaScript重点(总结一)
    第十章汽车租凭系统
    员工执行
    第六章预习
    第五章使用Dictionary替换List<t>实现功能
    第5章体检套餐管理系统
    JAVA面试题
    AJAX
    SSM中的登陆验证码
  • 原文地址:https://www.cnblogs.com/kangjianrong/p/9725068.html
Copyright © 2011-2022 走看看