ajax跨域請求時,sessionId不同,致使沒法記住登錄狀態

遇到這樣一個場景,就是前端的域是dev,請求接口時,接口的域是beta,即便在服務端設置了cookie存放的域,'COOKIE_DOMAIN'   =>  '.roboming.com',雖然cookie的域是正確了,但是sessionid的域仍是不對,狀況以下:
 
這個是登錄頁面
 
這是用戶列表頁,沒法獲取cookie,緣由是兩次請求不是同一個sessionid,服務器端,認爲尚未登錄
 

 

解決方法是:
 
一、php服務器端設置運行cros跨域請求
header("Access-Control-Allow-Origin:http://dev.roboming.com");
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
第二行代碼是容許客戶端帶上cookie
 
二、js的ajax,設置
xhrFields:{
    withCredentials:true
},
設置以後,再次請求,請求結果以下:
 
這一次,請求的時候,把全部cookie都帶上去了,第一次,之因此沒有帶上sessionid,由於sessionid的域是beta下的,而客戶端是在dev域下,因此請求時,沒法帶上beta域下的sessionid。
整個提交以下
$.ajax({
    url: 'http://beta.roboming.com/api.php?s=/Public/AdminLogin.html',
    type: 'POST',
    async:true,
    xhrFields:{
        withCredentials:true
    },
    data: {
        username:userName,
        password:pwd
    },
    success: function(respon){
        console.log(respon);
        var res=eval(respon);
    },
    error: function(){
        alert('服務器發生錯誤!');
    }
});
原理:

Cross-Origin Resource Sharing,跨域資源共享,簡稱 CORS,能夠做爲一種跨域請求以及響應的解決方案,不過,使用的頻率較少,緣由大概有如下幾種:javascript

一、資料較少,網上搜到的「經驗之談」絕大多數也都是你抄我,我cp他,使用不當還可能形成安全隱患。php

二、目前主流的處理方式是使用JSONP,易於實現,兼容性好,可查的資料也不少。而  IE10如下 版本的瀏覽器是不支持 CORS 的 ,所以,若是要求兼容IE瀏覽器,會致使使用此種方式的跨域請求以及傳遞Cookie的計劃夭折,最終還得迴歸JSONP。html

CORS的原理是:前端

W3C對你說:內個,同窗們,咱們爲了解決跨域通訊問題,新增了一個標準,你們在使用時,加一下就好了~java

雖然是一句玩笑話,但。。事實確實如此。咱們之因此可以「互聯」,協議 是根基。ajax

CORS的使用方式:api

如下均是模擬 從 A. abc.com  發起一個到 B. abc.com  的請求 的場景,即 本次 「跨域」 並不是 「大跨」,而是在 根域相同 的狀況下,去 請求 不一樣的子域 跨域

先解釋一下,爲何要用 子域之間的請求 做爲模擬場景:瀏覽器

這是由於多數人會認爲跨域,就是不一樣根域之間的請求,或者認爲根域相同的  不一樣的子域名之間是安全的調用,這些都是對跨域錯誤的認識。安全

實際上瀏覽器同源策略禁止了不一樣子域名之間的請求。 

需求一:能讓我跨就行

這也是最簡單的需求,在 B 的服務端程序中,增長響應頭:

// 使用通配符 * ,表示當前服務端 返回的信息容許全部源訪問, 不推薦

header( 'Access-Control-Allow-Origin:*' );

// 指定可信任的域名來接收響應信息, 推薦

header( 'Access-Control-Allow-Origin:http://A.abc.com' );

如此一來,一個跨域請求就不會被瀏覽器的 同源安全策略所阻止了。

需求二:跨過去之後,我還得操做Cookie

Well~ 讓咱們在 B 的服務端程序中,繼續補增響應頭:

// 容許攜帶 用戶認證憑據(也就是容許客戶端發送的請求攜帶Cookie)

header( 'Access-Control-Allow-Credentials:true' );

同時,A 在向 B 發起請求的時候,須要將 XMLHttpRequest 對象的  withCredentials 屬性設置爲 true,JQuery1.5.1+ 提供了相應的字段,使用方式以下:

$.ajax({ 
    url:"B. abc.com ", 
    xhrFields:{ 
        withCredentials:true 
    },
}); 

這樣,你會在 B 端發現:哦也~ 收到 Cookie 了。

設置 withCredentials 爲 true 的請求中會包含 A 端的全部Cookie,這些Cookie仍然遵循同源策略,因此,你只能訪問其中和 B 端同根域的Cookie,而沒法訪問其餘域Cookie。

總結一下就是:

要想跨域,你得有後臺(須要服務器端配合)。

BTW:Firefox,發現你和Chrome的表現不一致的狀況還真很少。Firefox中不要在同步模式(async:false)下傳遞Cookie哦~
相關文章
相關標籤/搜索