第04讲: 基础探究,Session 与 Cookies
我們在瀏覽網站的過程中,經常會遇到需要登錄的情況,而有些網頁只有登錄之后才可以訪問,而且登錄之后可以連續訪問很多次網站,但是有時候過一段時間就需要重新登錄。
還有一些網站,在打開瀏覽器時就自動登錄了,而且很長時間都不會失效,這種情況又是為什么?其實這里面涉及 Session 和 Cookies 的相關知識,本節就來揭開它們的神秘面紗。
1.靜態網頁和動態網頁
在開始介紹它們之前,我們需要先了解一下靜態網頁和動態網頁的概念。這里還是前面的示例代碼,內容如下:
<!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 等服務器,這樣這臺主機就可以作為服務器了,其他人便可以通過訪問服務器看到這個頁面,這就搭建了一個最簡單的網站。
這種網頁的內容是 HTML 代碼編寫的,文字、圖片等內容均通過寫好的 HTML 代碼來指定,這種頁面叫作靜態網頁。它加載速度快,編寫簡單,但是存在很大的缺陷,如可維護性差,不能根據 URL 靈活多變地顯示內容等。例如,我們想要給這個網頁的 URL 傳入一個 name 參數,讓其在網頁中顯示出來,是無法做到的。
因此,動態網頁應運而生,它可以動態解析 URL 中參數的變化,關聯數據庫并動態呈現不同的頁面內容,非常靈活多變。我們現在遇到的大多數網站都是動態網站,它們不再是一個簡單的 HTML,而是可能由 JSP、PHP、Python 等語言編寫的,其功能比靜態網頁強大和豐富太多了。
此外,動態網站還可以實現用戶登錄和注冊的功能。再回到開頭來看提到的問題,很多頁面是需要登錄之后才可以查看的。按照一般的邏輯來說,輸入用戶名和密碼登錄之后,肯定是拿到了一種類似憑證的東西,有了它,我們才能保持登錄狀態,才能訪問登錄之后才能看到的頁面。
那么,這種神秘的憑證到底是什么呢?其實它就是 Session 和 Cookies 共同產生的結果,下面我們來一探究竟。
2.無狀態 HTTP
在了解 Session 和 Cookies 之前,我們還需要了解 HTTP 的一個特點,叫作無狀態。
HTTP 的無狀態是指 HTTP 協議對事務處理是沒有記憶能力的,也就是說服務器不知道客戶端是什么狀態。
當我們向服務器發送請求后,服務器解析此請求,然后返回對應的響應,服務器負責完成這個過程,而且這個過程是完全獨立的,服務器不會記錄前后狀態的變化,也就是缺少狀態記錄。
這意味著如果后續需要處理前面的信息,則必須重傳,這也導致需要額外傳遞一些前面的重復請求,才能獲取后續響應,然而這種效果顯然不是我們想要的。為了保持前后狀態,我們肯定不能將前面的請求全部重傳一次,這太浪費資源了,對于這種需要用戶登錄的頁面來說,更是棘手。
這時兩個用于保持 HTTP 連接狀態的技術就出現了,它們分別是 Session 和 Cookies。Session 在服務端,也就是網站的服務器,用來保存用戶的 Session 信息;Cookies 在客戶端,也可以理解為瀏覽器端,有了 Cookies,瀏覽器在下次訪問網頁時會自動附帶上它發送給服務器,服務器通過識別 Cookies 并鑒定出是哪個用戶,然后再判斷用戶是否是登錄狀態,進而返回對應的響應。
我們可以理解為 Cookies 里面保存了登錄的憑證,有了它,只需要在下次請求攜帶 Cookies 發送請求而不必重新輸入用戶名、密碼等信息重新登錄了。
因此在爬蟲中,有時候處理需要登錄才能訪問的頁面時,我們一般會直接將登錄成功后獲取的 Cookies 放在請求頭里面直接請求,而不必重新模擬登錄。
好了,了解 Session 和 Cookies 的概念之后,我們在來詳細剖析它們的原理。
3.Session
Session,中文稱之為會話,其本身的含義是指有始有終的一系列動作 / 消息。比如,打電話時,從拿起電話撥號到掛斷電話這中間的一系列過程可以稱為一個 Session。
而在 Web 中,Session 對象用來存儲特定用戶 Session 所需的屬性及配置信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶 Session 中一直存在下去。當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有 Session,則 Web 服務器將自動創建一個 Session 對象。當 Session 過期或被放棄后,服務器將終止該 Session。
4.Cookies
Cookies 指某些網站為了辨別用戶身份、進行 Session 跟蹤而存儲在用戶本地終端上的數據。
5.Session 維持
那么,我們怎樣利用 Cookies 保持狀態呢?當客戶端第一次請求服務器時,服務器會返回一個響應頭中帶有 Set-Cookie 字段的響應給客戶端,用來標記是哪一個用戶,客戶端瀏覽器會把 Cookies 保存起來。當瀏覽器下一次再請求該網站時,瀏覽器會把此 Cookies 放到請求頭一起提交給服務器,Cookies 攜帶了 Session ID 信息,服務器檢查該 Cookies 即可找到對應的 Session 是什么,然后再判斷 Session 來以此來辨認用戶狀態。
在成功登錄某個網站時,服務器會告訴客戶端設置哪些 Cookies 信息,在后續訪問頁面時客戶端會把 Cookies 發送給服務器,服務器再找到對應的 Session 加以判斷。如果 Session 中的某些設置登錄狀態的變量是有效的,那就證明用戶處于登錄狀態,此時返回登錄之后才可以查看的網頁內容,瀏覽器再進行解析便可以看到了。
反之,如果傳給服務器的 Cookies 是無效的,或者 Session 已經過期了,我們將不能繼續訪問頁面,此時可能會收到錯誤的響應或者跳轉到登錄頁面重新登錄。
所以,Cookies 和 Session 需要配合,一個處于客戶端,一個處于服務端,二者共同協作,就實現了登錄 Session 控制。
6.屬性結構
接下來,我們來看看 Cookies 都有哪些內容。這里以知乎為例,在瀏覽器開發者工具中打開 Application 選項卡,然后在左側會有一個 Storage 部分,最后一項即為 Cookies,將其點開,如圖所示,這些就是 Cookies。
可以看到,這里有很多條目,其中每個條目可以稱為 Cookie。它有如下幾個屬性。
- Name,即該 Cookie 的名稱。Cookie 一旦創建,名稱便不可更改。
-Value,即該 Cookie 的值。如果值為 Unicode 字符,需要為字符編碼。如果值為二進制數據,則需要使用 BASE64 編碼。 - Max Age,即該 Cookie 失效的時間,單位秒,也常和 Expires 一起使用,通過它可以計算出其有效時間。Max Age 如果為正數,則該 Cookie 在 Max Age 秒之后失效。如果為負數,則關閉瀏覽器時 Cookie 即失效,瀏覽器也不會以任何形式保存該 Cookie。
- Path,即該 Cookie 的使用路徑。如果設置為 /path/,則只有路徑為 /path/ 的頁面可以訪問該 Cookie。如果設置為 /,則本域名下的所有頁面都可以訪問該 Cookie。
- Domain,即可以訪問該 Cookie 的域名。例如如果設置為 .zhihu.com,則所有以 zhihu.com,結尾的域名都可以訪問該 Cookie。
- Size 字段,即此 Cookie 的大小。
- Http 字段,即 Cookie 的 httponly 屬性。若此屬性為 true,則只有在 HTTP Headers 中會帶有此 Cookie 的信息,而不能通過 document.cookie 來訪問此 Cookie。
- Secure,即該 Cookie 是否僅被使用安全協議傳輸。安全協議。安全協議有 HTTPS、SSL 等,在網絡上傳輸數據之前先將數據加密。默認為 false。
7.會話 Cookie 和持久 Cookie
從表面意思來說,會話 Cookie 就是把 Cookie 放在瀏覽器內存里,瀏覽器在關閉之后該 Cookie 即失效;持久 Cookie 則會保存到客戶端的硬盤中,下次還可以繼續使用,用于長久保持用戶登錄狀態。
其實嚴格來說,沒有會話 Cookie 和持久 Cookie 之 分,只是由 Cookie 的 Max Age 或 Expires 字段決定了過期的時間。
因此,一些持久化登錄的網站其實就是把 Cookie 的有效時間和 Session 有效期設置得比較長,下次我們再訪問頁面時仍然攜帶之前的 Cookie,就可以直接保持登錄狀態。
8.常見誤區
在談論 Session 機制的時候,常常聽到這樣一種誤解 ——“只要關閉瀏覽器,Session 就消失了”。可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對 Session 來說,也是一樣,除非程序通知服務器刪除一個 Session,否則服務器會一直保留。比如,程序一般都是在我們做注銷操作時才去刪除 Session。
但是當我們關閉瀏覽器時,瀏覽器不會主動在關閉之前通知服務器它將要關閉,所以服務器根本不會有機會知道瀏覽器已經關閉。之所以會有這種錯覺,是因為大部分網站都使用會話 Cookie 來保存 Session ID 信息,而關閉瀏覽器后 Cookies 就消失了,再次連接服務器時,也就無法找到原來的 Session 了。如果服務器設置的 Cookies 保存到硬盤上,或者使用某種手段改寫瀏覽器發出的 HTTP 請求頭,把原來的 Cookies 發送給服務器,則再次打開瀏覽器,仍然能夠找到原來的 Session ID,依舊還是可以保持登錄狀態的。
而且恰恰是由于關閉瀏覽器不會導致 Session 被刪除,這就需要服務器為 Session 設置一個失效時間,當距離客戶端上一次使用 Session 的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把 Session 刪除以節省存儲空間。
總結
以上是生活随笔為你收集整理的第04讲: 基础探究,Session 与 Cookies的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第34讲:更好用的自动化工具 airte
- 下一篇: 第03讲. 原理探究,了解爬虫的基本原理