在瀏覽網站的過程當中,咱們常常會遇到須要登陸的狀況,有些頁面只有登陸以後才能夠訪問,並且登陸以後能夠連續訪問不少次網站,可是有時候過一段時間就須要從新登陸。還有一些網站,在打開瀏覽器時就自動登陸了,並且很長時間都不會失效,這種狀況又是爲何?其實這裏面涉及會話和Cookies的相關知識,本節就來揭開它們的神祕面紗。html
在開始以前,咱們須要先了解一下靜態網頁和動態網頁的概念。這裏仍是前面的示例代碼,內容以下:git
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h2 class="title">Hello World</h2>
<p class="text">Hello, this is a paragraph.</p>
</div>
</div>
</body>
</html>
|
這是最基本的HTML代碼,咱們將其保存爲一個.html文件,而後把它放在某臺具備固定公網IP的主機上,主機上裝上Apache或Nginx等服務器,這樣這臺主機就能夠做爲服務器了,其餘人即可以經過訪問服務器看到這個頁面,這就搭建了一個最簡單的網站。github
這種網頁的內容是HTML代碼編寫的,文字、圖片等內容均經過寫好的HTML代碼來指定,這種頁面叫做靜態網頁。它加載速度快,編寫簡單,可是存在很大的缺陷,如可維護性差,不能根據URL靈活多變地顯示內容等。例如,咱們想要給這個網頁的URL傳入一個name
參數,讓其在網頁中顯示出來,是沒法作到的。數據庫
所以,動態網頁應運而生,它能夠動態解析URL中參數的變化,關聯數據庫並動態呈現不一樣的頁面內容,很是靈活多變。咱們如今遇到的大多數網站都是動態網站,它們再也不是一個簡單的HTML,而是可能由JSP、PHP、Python等語言編寫的,其功能比靜態網頁強大和豐富太多了。瀏覽器
此外,動態網站還能夠實現用戶登陸和註冊的功能。再回到開頭提到的問題,不少頁面是須要登陸以後才能夠查看的。按照通常的邏輯來講,輸入用戶名和密碼登陸以後,確定是拿到了一種相似憑證的東西,有了它,咱們才能保持登陸狀態,才能訪問登陸以後才能看到的頁面。安全
那麼,這種神祕的憑證究竟是什麼呢?其實它就是會話和Cookies共同產生的結果,下面咱們來一探究竟。服務器
在瞭解會話和Cookies以前,咱們還須要瞭解HTTP的一個特色,叫做無狀態。cookie
HTTP的無狀態是指HTTP協議對事務處理是沒有記憶能力的,也就是說服務器不知道客戶端是什麼狀態。當咱們向服務器發送請求後,服務器解析此請求,而後返回對應的響應,服務器負責完成這個過程,並且這個過程是徹底獨立的,服務器不會記錄先後狀態的變化,也就是缺乏狀態記錄。這意味着若是後續須要處理前面的信息,則必須重傳,這致使須要額外傳遞一些前面的重複請求,才能獲取後續響應,然而這種效果顯然不是咱們想要的。爲了保持先後狀態,咱們確定不能將前面的請求所有重傳一次,這太浪費資源了,對於這種須要用戶登陸的頁面來講,更是棘手。網絡
這時兩個用於保持HTTP鏈接狀態的技術就出現了,它們分別是會話和Cookies。會話在服務端,也就是網站的服務器,用來保存用戶的會話信息;Cookies在客戶端,也能夠理解爲瀏覽器端,有了Cookies,瀏覽器在下次訪問網頁時會自動附帶上它發送給服務器,服務器經過識別Cookies並鑑定出是哪一個用戶,而後再判斷用戶是不是登陸狀態,而後返回對應的響應。session
咱們能夠理解爲Cookies裏面保存了登陸的憑證,有了它,只須要在下次請求攜帶Cookies發送請求而沒必要從新輸入用戶名、密碼等信息從新登陸了。
所以在爬蟲中,有時候處理須要登陸才能訪問的頁面時,咱們通常會直接將登陸成功後獲取的Cookies放在請求頭裏面直接請求,而沒必要從新模擬登陸。
好了,瞭解會話和Cookies的概念以後,咱們在來詳細剖析它們的原理。
會話,其原本的含義是指善始善終的一系列動做/消息。好比,打電話時,從拿起電話撥號到掛斷電話這中間的一系列過程能夠稱爲一個會話。
而在Web中,會話對象用來存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的Web頁之間跳轉時,存儲在會話對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程序的Web頁時,若是該用戶尚未會話,則Web服務器將自動建立一個會話對象。當會話過時或被放棄後,服務器將終止該會話。
Cookies指某些網站爲了辨別用戶身份、進行會話跟蹤而存儲在用戶本地終端上的數據。
那麼,咱們怎樣利用Cookies保持狀態呢?當客戶端第一次請求服務器時,服務器會返回一個請求頭中帶有Set-Cookie
字段的響應給客戶端,用來標記是哪個用戶,客戶端瀏覽器會把Cookies保存起來。當瀏覽器下一次再請求該網站時,瀏覽器會把此Cookies放到請求頭一塊兒提交給服務器,Cookies攜帶了會話ID信息,服務器檢查該Cookies便可找到對應的會話是什麼,而後再判斷會話來以此來辨認用戶狀態。
在成功登陸某個網站時,服務器會告訴客戶端設置哪些Cookies信息,在後續訪問頁面時客戶端會把Cookies發送給服務器,服務器再找到對應的會話加以判斷。若是會話中的某些設置登陸狀態的變量是有效的,那就證實用戶處於登陸狀態,此時返回登陸以後才能夠查看的網頁內容,瀏覽器再進行解析即可以看到了。
反之,若是傳給服務器的Cookies是無效的,或者會話已通過期了,咱們將不能繼續訪問頁面,此時可能會收到錯誤的響應或者跳轉到登陸頁面從新登陸。
因此,Cookies和會話須要配合,一個處於客戶端,一個處於服務端,兩者共同協做,就實現了登陸會話控制。
接下來,咱們來看看Cookies都有哪些內容。這裏以知乎爲例,在瀏覽器開發者工具中打開Application選項卡,而後在左側會有一個Storage部分,最後一項即爲Cookies,將其點開,如圖2-13所示,這些就是Cookies。
圖2-13 Cookies列表
能夠看到,這裏有不少條目,其中每一個條目能夠稱爲Cookie。它有以下幾個屬性。
httponly
屬性。若此屬性爲true
,則只有在HTTP頭中會帶有此Cookie的信息,而不能經過document.cookie
來訪問此Cookie。false
。從表面意思來講,會話Cookie就是把Cookie放在瀏覽器內存裏,瀏覽器在關閉以後該Cookie即失效;持久Cookie則會保存到客戶端的硬盤中,下次還能夠繼續使用,用於長久保持用戶登陸狀態。
其實嚴格來講,沒有會話Cookie和持久Cookie之分,只是由Cookie的Max Age或Expires字段決定了過時的時間。
所以,一些持久化登陸的網站其實就是把Cookie的有效時間和會話有效期設置得比較長,下次咱們再訪問頁面時仍然攜帶以前的Cookie,就能夠直接保持登陸狀態。
在談論會話機制的時候,經常聽到這樣一種誤解「只要關閉瀏覽器,會話就消失了」,這種理解是錯誤的。能夠想象一下會員卡的例子,除非顧客主動對店家提出銷卡,不然店家絕對不會輕易刪除顧客的資料。對會話來講,也是同樣,除非程序通知服務器刪除一個會話,不然服務器會一直保留。好比,程序通常都是在咱們作註銷操做時纔去刪除會話。
可是當咱們關閉瀏覽器時,瀏覽器不會主動在關閉以前通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器已經關閉。之因此會有這種錯覺,是由於大部分會話機制都使用會話Cookie來保存會話ID信息,而關閉瀏覽器後Cookies就消失了,再次鏈接服務器時,也就沒法找到原來的會話了。若是服務器設置的Cookies保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的Cookies發送給服務器,則再次打開瀏覽器,仍然可以找到原來的會話 ID,依舊仍是能夠保持登陸狀態的。
並且偏偏是因爲關閉瀏覽器不會致使會話被刪除,這就須要服務器爲會話設置一個失效時間,當距離客戶端上一次使用會話的時間超過這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把會話刪除以節省存儲空間。
因爲涉及一些專業名詞知識,本節的部份內容參考來源以下。