zoukankan      html  css  js  c++  java
  • Ajax跨域请求,无法传递及接收cookie信息

    最近在做一个系统遇到一个问题,在网上找个一个和我遇到相同问题的(原文地址:https://www.cnblogs.com/helloyy/p/6109665.html)按照他的步骤还是没有解决,继续查找资料,根据他的方法做出修改,最后解决。(不想写字就自己拿过来了。。)

    应用场景:

      项目测试环境:前端应用HTML,js,jQuery ajax请求,部署在Apache服务器;后端业务系统应用spring mvc,mybatis,部署在tomcat服务器。当在一个系统需要调用另一个系统的时候,就会出现跨域的问题,即本次我们遇到了ajax请求的跨域问题。

      系统权限安全框架使用shiro,系统登录时发送ajax请求调用springmvc action方法进行系统登录及身份认证,角色权限授权等。由于ajax请求时,浏览器会认为携带Cookie是不安全请求,将限制其携带Cookie信息,导致登录action方法无法获取并响应相应的Cookie(JSESSIONID),身份认证及角色权限授权、退出等都操作都无法正常使用。

    解决方案:

      1、当发送ajax请求时,查看浏览器调试信息中Headers和Cookies,发现发送到后端的跨域请求并没有携带 cookie 信息,可见Request Headers不包含Cookie属性,Response Headers中也不包含Set-Cookie属性,导致无法得到后台业务系统的认证。

     

      解决:在ajax里添加withCredentials的配置,允许其请求携带cookie信息。通过设置withCredentials=true,发送Ajax时,Request header中便会带上 Cookie 信息。

    $.ajax({
                type: "post",
                url:url,
                async:false,
                data:datatosend,
                dataType:"json",
                beforeSend: function(xhr) {
                    xhr.withCredentials = true;
                }
                crossDomain:true,
                success: function (data) {
                    var a=JSON.stringify(data);
                    if(data.result==true){
                      ...........
                   }else{
                   ...........
                 }
                },
                error:function (data) {
                    var a=JSON.stringify(data);
                    alert(a);
                }
            });

    注意:<踩过的坑>我们在beforeSend方法里设置withCredentials=true;在上述代码情境下,如果使用xhrFields:{ withCredentials:true }方法,则允许携带cookie信息的配置并不生效。(原因:ajax中添加了async:false,即修改为同步了,在窗口上下文的同步模式中,已不再支持使用XMLHttpRequest的withCredentials属性)。当保持异步模式时,我们可以更换对应的方法。注意2种方法的区分。

       2、服务器server端要配置Access-Control-Allow-Credentials

      我们在客户端设置了withCredentials=true 参数,对应着,服务器端要通过在响应 header 中设置Access-Control-Allow-Credentials = true来运行客户端携带证书式的访问。通过对Credentials参数的设置,就可以保持跨域Ajax时传递的Cookie。

    response.setHeader("Access-Control-Allow-Credentials", "true");

      3、服务器server端要配置Access-Control-Allow-Origin

      到以上配置为止,发送ajax请求,我们发现还会出现一个错误,提示我们 Access-Control-Allow-Origin 不能用 * 通配符。原因是:当服务器端 Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin 的值不能为 '*' 。

      我们重新设置Access-Control-Allow-Origin的值,当服务器端接收到请求后,在返回响应时,把请求的域Origin填写到响应的Header信息里(即谁访问我,我允许谁),代码如下:

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

      ok,到目前问题搞定了,经过测试,可成功传递及响应cookie信息,浏览器调试信息如下图所示:

       

      

      

      

      他的是解决了,但是我的还是不行。最后做如下修改,完美解决。

    1,前端请求

            $.ajax({
                type: "post",
                cache: false,   //是否缓存
                async:false,    //同步
                url:"http://xxxxxxxxx",
                xhrFields: {withCredentials: true},
                crossDomain:true,       //允许跨域
                success:function (data) {
                    alert(data.code);
                }
            });

    2,服务端配置

            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
  • 相关阅读:
    基于Linux C的socketEthereal程序和Package分析 (一个)
    [Firebase + PWA] Keynote: Progressive Web Apps on Firebase
    [Redux] Navigating with React Router <Link>
    [Redux] Adding React Router to the Project
    [Redux] Refactoring the Entry Point
    [Redux] Persisting the State to the Local Storage
    [Redux] Supplying the Initial State
    [PWA] Caching with Progressive libraries
    [TypeScript] Understanding Generics with RxJS
    [React + Mobx] Mobx and React intro: syncing the UI with the app state using observable and observer
  • 原文地址:https://www.cnblogs.com/chancy/p/9988085.html
Copyright © 2011-2022 走看看