天天看點

你真的了解 Cookie 和 Session 嗎?

我在做面試官的時候,曾經問過很多朋友這個問題: Cookie 和 Session 有什麼差別呢?大部分的面試者應該都可以說上一兩句,比如:什麼是 Cookie?什麼是 Session?兩者的差別等。

但如果再往深入探讨的話,就慢慢有一些朋友不太了解了,談起原理時就很少有朋友全部回答準确。今天和大家一起深入聊聊有關 Cookie 和 Session 的話題 。

什麼是 Cookie 和 Session ?初級程式員高頻面試題。

什麼是 Cookie

HTTP Cookie(也叫 Web Cookie或浏覽器 Cookie)是伺服器發送到使用者浏覽器并儲存在本地的一小塊資料,它會在浏覽器下次向同一伺服器再發起請求時被攜帶并發送到伺服器上。通常,它用于告知服務端兩個請求是否來自同一浏覽器,如保持使用者的登入狀态。Cookie 使基于無狀态的 HTTP 協定記錄穩定的狀态資訊成為了可能。

Cookie 主要用于以下三個方面:

會話狀态管理(如使用者登入狀态、購物車、遊戲分數或其它需要記錄的資訊)

個性化設定(如使用者自定義設定、主題等)

浏覽器行為跟蹤(如跟蹤分析使用者行為等)

什麼是 Session

Session 代表着伺服器和用戶端一次會話的過程。Session 對象存儲特定使用者會話所需的屬性及配置資訊。這樣,當使用者在應用程式的 Web 頁之間跳轉時,存儲在 Session 對象中的變量将不會丢失,而是在整個使用者會話中一直存在下去。當用戶端關閉會話,或者 Session 逾時失效時會話結束。

Cookie 和 Session 有什麼不同?

作用範圍不同,Cookie 儲存在用戶端(浏覽器),Session 儲存在伺服器端。

存取方式的不同,Cookie 隻能儲存 ASCII,Session 可以存任意資料類型,一般情況下我們可以在 Session 中保持一些常用變量資訊,比如說 UserId 等。

有效期不同,Cookie 可設定為長時間保持,比如我們經常使用的預設登入功能,Session 一般失效時間較短,用戶端關閉或者 Session 逾時都會失效。

隐私政策不同,Cookie 存儲在用戶端,比較容易遭到不法擷取,早期有人将使用者的登入名和密碼存儲在 Cookie 中導緻資訊被竊取;Session 存儲在服務端,安全性相對 Cookie 要好一些。

存儲大小不同, 單個 Cookie 儲存的資料不能超過 4K,Session 可存儲資料遠高于 Cookie。

前兩層樓内容,絕大部分同學都可以準确回答

為什麼需要 Cookie 和 Session,他們有什麼關聯?

說起來為什麼需要 Cookie ,這就需要從浏覽器開始說起,我們都知道浏覽器是沒有狀态的(HTTP 協定無狀态),這意味着浏覽器并不知道是張三還是李四在和服務端打交道。這個時候就需要有一個機制來告訴服務端,本次操作使用者是否登入,是哪個使用者在執行的操作,那這套機制的實作就需要 Cookie 和 Session 的配合。

那麼 Cookie 和 Session 是如何配合的呢?我畫了一張圖大家可以先了解下。

使用者第一次請求伺服器的時候,伺服器根據使用者送出的相關資訊,建立建立對應的 Session ,請求傳回時将此 Session 的唯一辨別資訊 SessionID 傳回給浏覽器,浏覽器接收到伺服器傳回的 SessionID 資訊後,會将此資訊存入到 Cookie 中,同時 Cookie 記錄此 SessionID 屬于哪個域名。

當使用者第二次通路伺服器的時候,請求會自動判斷此域名下是否存在 Cookie 資訊,如果存在自動将 Cookie 資訊也發送給服務端,服務端會從 Cookie 中擷取 SessionID,再根據 SessionID 查找對應的 Session 資訊,如果沒有找到說明使用者沒有登入或者登入失效,如果找到 Session 證明使用者已經登入可執行後面操作。

根據以上流程可知,SessionID 是連接配接 Cookie 和 Session 的一道橋梁,大部分系統也是根據此原理來驗證使用者登入狀态。

三層樓的内容,大部分同學可以講清楚。

既然服務端是根據 Cookie 中的資訊判斷使用者是否登入,那麼如果浏覽器中禁止了 Cookie,如何保障整個機制的正常運轉。

第一種方案,每次請求中都攜帶一個 SessionID 的參數,也可以 Post 的方式送出,也可以在請求的位址後面拼接 <code>xxx?SessionID=123456...</code>。

第二種方案,Token 機制。Token 機制多用于 App 用戶端和伺服器互動的模式,也可以用于 Web 端做使用者狀态管理。

Token 的意思是“令牌”,是服務端生成的一串字元串,作為用戶端進行請求的一個辨別。Token 機制和 Cookie 和 Session 的使用機制比較類似。

當使用者第一次登入後,伺服器根據送出的使用者資訊生成一個 Token,響應時将 Token 傳回給用戶端,以後用戶端隻需帶上這個 Token 前來請求資料即可,無需再次登入驗證。

四層樓的内容,一部分同學可以講清楚。

如何考慮分布式 Session 問題?

在網際網路公司為了可以支撐更大的流量,後端往往需要多台伺服器共同來支撐前端使用者請求,那如果使用者在 A 伺服器登入了,第二次請求跑到服務 B 就會出現登入失效問題。

分布式 Session 一般會有以下幾種解決方案:

Nginx ip_hash 政策,服務端使用 Nginx 代理,每個請求按通路 IP 的 hash 配置設定,這樣來自同一 IP 固定通路一個背景伺服器,避免了在伺服器 A 建立 Session,第二次分發到伺服器 B 的現象。

Session 複制,任何一個伺服器上的 Session 發生改變(增删改),該節點會把這個 Session 的所有内容序列化,然後廣播給所有其它節點。

共享 Session,服務端無狀态話,将使用者的 Session 等資訊使用緩存中間件來統一管理,保障分發到每一個伺服器的響應結果都一緻。

建議采用第三種方案。

如何解決跨域請求?Jsonp 跨域的原理是什麼?

說起跨域請求,必須要了解浏覽器的同源政策,同源政策/SOP(Same origin policy)是一種約定,由 Netscape 公司 1995年引入浏覽器,它是浏覽器最核心也最基本的安全功能,如果缺少了同源政策,浏覽器很容易受到 XSS、CSFR 等攻擊。所謂同源是指"協定+域名+端口"三者相同,即便兩個不同的域名指向同一個 ip 位址,也非同源。

解決跨域請求的常用方法是:

通過代理來避免,比如使用 Nginx 在後端轉發請求,避免了前端出現跨域的問題。

通過 Jsonp 跨域

其它跨域解決方案

重點談一下 Jsonp 跨域原理。浏覽器的同源政策把跨域請求都禁止了,但是頁面中的 <code>&lt;script&gt;&lt;img&gt;&lt;iframe&gt;</code>标簽是例外,不受同源政策限制。Jsonp 就是利用 <code>&lt;script&gt;</code> 标簽跨域特性進行跨域資料通路。

JSONP 的理念就是,與服務端約定好一個回調函數名,服務端接收到請求後,将傳回一段 Javascript,在這段 Javascript 代碼中調用了約定好的回調函數,并且将資料作為參數進行傳遞。當網頁接收到這段 Javascript 代碼後,就會執行這個回調函數,這時資料已經成功傳輸到用戶端了。

JSONP 的缺點是:它隻支援 GET 請求,而不支援 POST 請求等其他類型的 HTTP 請求。

以上就是有關 Cookie 和 Session 常見的面試點,不知道有多少同學可以在面試中準确回答所有問題。

作者:純潔的微笑

出處:www.ityouknow.com

資源:微信搜【純潔的微笑】關注我,回複 【程式員】【面試】【架構師】有我準備的一線程式必備計算機書籍、大廠面試資料和免費電子書。 一共1024G的資料,希望可以幫助大家提升技術和能力。

本文如對您有幫助,還請多幫 【推薦】 下此文。

點我了解:Tooool-程式員一站式導航網站