Ajax跨域請求action方法,無法傳遞及接收cookie信息(應用於系統登錄認證及退出)解決方案


  最近的項目中涉及到了應用ajax請求后台系統登錄,身份認證失敗,經過不斷的調試終於找到解決方案。

應用場景:

  項目測試環境:前端應用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信息,瀏覽器調試信息如下圖所示:

   

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM