Cookie中的sessionid與JSONP原理


一、首先說明一下cookie中的sessionid的作用。

1、cookie只是一些文本內容,多是鍵值對的形式,是請求頭中的一部分

2、http是無連接的

知道這兩點,就可以很容易的理解sessionid的作用的。

session是保存在服務器端的,與客戶端的一次會話。session中用於保存會話的一些內容,可以理解為服務器給一個用戶開辟出來的一段內存空間用於保存這次會話的一些內容。

問題在於http是無連接的,所以在http請求結束之后,第二次請求過來時,服務器端是不會知道這次的請求是誰發送的,以及上一次通信的session是什么。這些都是無從得知的,要想知道這次通信,對應的哪個session,就需要cookie來標記了。在cookie中,只要有一次通信,基本上就會有sessionid存在(取決於服務器,應用服務器都會放置sessionid,如tomcat放在cookie中的sessionid叫做jsessionid),在第二次請求時,服務器從cookie中獲取sessionid參數,在自己現有的session中尋找該id,如果存在則用此session作為這次通信的session,如果不存在,則重新創建一個。session是會過期的,原因也在這里,服務器是不會知道客戶端(瀏覽器)是否還會進行第二次請求,而且cookie是可以手動清空的,如果一直為其保留session,該session可能永遠不會用到,這樣下來服務器的內存肯定會承受不了,所以session是一定要有過期這個概念的。

同時,由於一些瀏覽器,不支持cookie,這個時候sessionid放在哪里呢?放在url中,因為Session默認是需要Cookie支持的,但有些客戶瀏覽器是關閉Cookie的,而jsessionid是存儲在Cookie中的,如果禁用Cookie的話,也就是說服務器那邊得不到jsessionid,這樣也就沒法根據jsessionid獲得對應的session了,獲得不了session就得不到session中存儲的數據了。這個時候就需要在URL中指定服務器上的session標識,也就是類似於“jsessionid=5F4771183629C9834F8382E23BE13C4C” 這種格式。

用一個方法(忘了方法的名字)處理URL串就可以得到這個東西,這個方法會判斷你的瀏覽器是否開啟了Cookie,如果他認為應該加他就會加上去。
摘抄:所謂session你可以這樣理解:當你與服務端進行會話時,比如說登陸成功后,服務端會為你開壁一塊內存區間,用以存放你這次會話的一些內容,比如說用戶名之類的。那么就需要一個東西來標志這個內存區間是你的而不是別人的,這個東西就是session id(jsessionid只是tomcat中對session id的叫法,在其它容器里面,不一定就是叫jsessionid了。),而這個內存區間你可以理解為session。
然后,服務器會將這個session id發回給你的瀏覽器,放入你的瀏覽器的cookies中(這個cookies是內存cookies,跟一般的不一樣,它會隨着瀏覽器的關閉而消失)。
之后,只有你瀏覽器沒有關閉,你每向服務器發請求,服務器就會從你發送過來的cookies中拿出這個session id,然后根據這個session id到相應的內存中取你之前存放的數據。
但是,如果你退出登陸了,服務器會清掉屬於你的內存區域,所以你再登的話,會產生一個新的session了。
不好意思,我可能說得不太清楚,但這方面的知識網上有不少,你可以了解下session的原理。
session是有一定作用域的,而且是有時間限制的。
jsessionid是服務器那邊生成的,因為cookie是服務器那邊送到客戶端的信息。不管能不能修改jsessionid,都不應該修改,如果你修改了,這就失去了jessionid的自身意義了,你修改的話,你讓服務器那邊如何找到對應的session?找不到的話,你存放在那個session中的數據不是取不到了嗎?
登陸然后退出,我認為會重新生成一個jsessionid。因為退出的話,application作用域的數據都會丟失,更何況這個比它作用域還小的session?既然session都消失了,這個jsessionid有什么用?存入后url格式為:wapbrowse.jsp;jsessionid=5AC6268DD8D4D5D1FDF5D41E9F2FD960?curAlbumID=9
 
二、JS跨域與JSONP
由於JS同源策略的影響,XmlHttpRequest(即Ajax請求對象)的請求是不能跨域的:
URL 說明 是否允許通信
http://www.a.com/a.js 
http://www.a.com/b.js
同一域名下 允許
http://www.a.com/lab/a.js 
http://www.a.com/script/b.js
同一域名下不同文件夾 允許
http://www.a.com:8000/a.js 
http://www.a.com/b.js
同一域名,不同端口 不允許
http://www.a.com/a.js 
https://www.a.com/b.js
同一域名,不同協議 不允許
http://www.a.com/a.js 
http://70.32.92.74/b.js
域名和域名對應ip 不允許
http://www.a.com/a.js 
http://script.a.com/b.js
主域相同,子域不同 不允許
http://www.a.com/a.js 
http://a.com/b.js
同一域名,不同二級域名(同上) 不允許(cookie這種情況下也不允許訪問)
http://www.cnblogs.com/a.js 
http://www.a.com/b.js
不同域名 不允許
但是,在頁面上引入不同域上的js腳本文件卻是可以的,jsonp正是利用這個特性來實現的。即通過<script src="http://url" type="text/javascript">標簽引入js文件。
比如,有個a.html頁面,它里面的代碼需要利用ajax獲取一個不同域上的json數據,假設這個json數據地址是http://example.com/data.php,那么a.html中的代碼就可以這樣:
服務器端則需要返回js代碼,而不能只返回json對象,js代碼為dosomething(jsondata),這樣到前台來,就相當於直接執行了前台的方法dosomething,遠程的json數據也就傳過來的。
這個是php服務器端的特殊處理,只用在原json對象變為callback(json對象)即可。

所以通過http://example.com/data.php?callback=dosomething得到的js文件,就是我們之前定義的dosomething函數,並且它的參數就是我們需要的json數據,這樣我們就跨域獲得了我們需要的數據。

這樣jsonp的原理就很清楚了,通過script標簽引入一個js文件,這個js文件載入成功后會執行我們在url參數中指定的函數,並且會把我們需要的json數據作為參數傳入。所以jsonp是需要服務器端的頁面進行相應的配合的。

知道jsonp跨域的原理后我們就可以用js動態生成script標簽來進行跨域操作了,而不用特意的手動的書寫那些script標簽。如果你的頁面使用jquery,那么通過它封裝的方法就能很方便的來進行jsonp操作了。

下面為其他示例:

服務器端:

        protected void Page_Load(object sender, EventArgs e)
        {
            string result = "callback({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";

            Response.Clear();
            Response.Write(result);
            Response.End();
        }

客戶端:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">

        var result = null;
        window.onload = function () {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "http://192.168.0.101/ExampleBusinessApplication.Web/web2.aspx";

            var head = document.getElementsByTagName("head")[0];
            head.insertBefore(script, head.firstChild);

        };

        function callback(data) {
            result = data;
        }

        function b_click() {
            alert(result.name);
        }
    </script>
</head>
<body>
    <input type="button" value="click me!" onclick="b_click();" />
</body>
</html>

 同時通過jQuery可以簡單的實現這個功能:

通過jquery的jsonp的方式.使用此方式,對服務器端有要求.

服務器端如下:

        protected void Page_Load(object sender, EventArgs e)
        {
            string callback = Request.QueryString["jsoncallback"];

            string result = callback + "({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";

            Response.Clear();
            Response.Write(result);
            Response.End();
        }


客戶端:

$.ajax({ 
                async: false, 
                url: "http://192.168.0.5/Web/web1.aspx", 
                type: "GET", 
                dataType: 'jsonp', 
                //jsonp的值自定義,如果使用jsoncallback,那么服務器端,要返回一個jsoncallback的值對應的對象. 
                jsonp: 'jsoncallback', 
                //要傳遞的參數,沒有傳參時,也一定要寫上 
                  data: null, 
                timeout: 5000, 
                //返回Json類型 
                  contentType: "application/json;utf-8", 
                //服務器段返回的對象包含name,data屬性. 
                success: function (result) { 
                    alert(result.date); 
                }, 
                error: function (jqXHR, textStatus, errorThrown) { 
                    alert(textStatus); 
                } 
            });

實際上,在我們執行這段js時,js向服務器發出了這樣一個請求:

http://192.168.0.5/Web/web1.aspx?jsoncallback=jsonp1354505244726&_=1354505244742 

而服務器也相應的返回了如下對象:

jsonp1354506338864({"name":"zhangsan","date":"2012-12-03"})
此時就實現了跨域范文數據的要求.

簡單方法:

原理是一樣的,只不過我們不需要手動的插入script標簽以及定義回掉函數。jquery會自動生成一個全局函數來替換callback=?中的問號,之后獲取到數據后又會自動銷毀,實際上就是起一個臨時代理函數的作用。$.getJSON方法會自動判斷是否跨域,不跨域的話,就調用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調用jsonp的回調函數。

 其他跨域方法有:http://www.cnblogs.com/2050/p/3191744.html


免責聲明!

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



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