HTTP 是一種不儲存狀態的協定,即無狀態協定,HTTP 協定不會儲存請求和響應之間的通訊狀態,協定對於傳送過的請求和響應都不會做持久化處理。
無狀態協定減少了對服務壓力,如果一個伺服器需要處理百萬級使用者
的請求狀態,對伺服器的壓力無疑的是巨大的。
無狀態的 HTTP 由於其簡單和易用性,應用比較管廣泛。而且早期的 Web 服務對於狀態的需求也很低,所以應用場景也比較廣泛。
隨著 Web 的不斷髮展,越來越多的服務需要記錄使用者的登入狀態,比如購物、聊天、論壇服務,請求都是無狀態的服務,伺服器就無法識別是 HTTP 請求的使用者資訊,所以就需要一種技術儲存使用者的狀態,也就 Cookie 技術,有了 Cookie 的 HTTP 協定通訊,就能儲存狀態了。
在無狀態協定不受影響的基礎上,通過引入 Cookie 來記錄狀態,這樣既不會影響原有的功能,也可以解決請求狀態問題。Cookie 是當你瀏覽網頁,通過伺服器記錄你的使用者名稱,密碼等網頁資訊。
Cookie 是由伺服器端建立,使用者端向服務傳送請求後,伺服器端通過響應報文的Set-Cookie 欄位將 Cookie 資訊返回給使用者端,使用者端自動儲存 Cookie。Cookie 會標記來源、有效期、路徑等資訊。使用者端再次請求該伺服器端時,會自動將 Cookie 新增到請求報文中(Request Header),伺服器端就能通過傳遞的 Cookie 識別使用者端的資訊。
1.沒有 Cookie 資訊的請求:
2.再次(有了Cookie資訊後)傳送請求:
使用 Spring Boot 建立簡單的 Controller,當用戶端傳遞的引數 a 有值時,伺服器端才新增 Cookie:
@GetMapping("/cookie")
@ResponseBody
public String cookie(String a, HttpServletRequest request, HttpServletResponse response) {
if (a != null) {
Cookie cookie = new Cookie("name",a);
response.addCookie(cookie);
}
return "ok";
}
首先使用 Chrome 瀏覽器傳送請求http://localhost:8080/cookie
:
返回結果沒有 Cookie。
再傳送帶有 a 引數的請求http://localhost:8080/cookie?a=jeremy
:
返回 Cookie 都存在 Set-Cookie 欄位中,使用者端會自動儲存 Cookie。
再次傳送相同的請求http://localhost:8080/cookie?a=jeremy
:
請求會將使用者端的 Cooike 自動新增到請求報文中,此時伺服器端也能接收到 Cookie資訊:
Session 是伺服器端儲存使用者狀態的一種機制,當用戶存取網站時,伺服器端會為每個使用者建立唯一個對談標識,並根據使用者登入請求建立和儲存對談資訊,使用者端再次請求時,就能從伺服器端獲取對談資訊了。
在 Java 中的 Servlet 提供 HttpSession 的介面來操作對談資訊,只要有以下幾個方法:
HttpSession 介面通過 getAttribute() 和 setAttribute() 來獲取和設定對談資訊,
下面建立兩個方法,session() 方法獲取對談判斷使用者是否登入,login() 方法新增對談資訊。
@GetMapping("/session")
@ResponseBody
public String session(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
Boolean login =(Boolean) session.getAttribute("login");
String loginInfo;
if (login == null) {
loginInfo = "未登入";
} else {
loginInfo = "已登入";
}
return "session id :" + session.getId() + ":" + loginInfo;
}
@GetMapping("/login")
@ResponseBody
public String login(HttpServletRequest request) {
HttpSession session = request.getSession();
session.setAttribute("login",true);
return "ok";
}
先請求 http://localhost:8080/session
,返回如下資訊:
session id :F3C560208A54E3D5B465CDEBE7419817:未登入
多次傳送請求,session id 是一致的,說明 session id是在對談週期之內(瀏覽器不關閉)都是不變的。
然後請求登入介面 http://localhost:8080/login
,設定了對談資訊之後,再請求 http://localhost:8080/session
:返回如下資訊:
session id :F3C560208A54E3D5B465CDEBE7419817:已登入
同一個使用者請求,伺服器端會建立唯一的對談,在請求的生命週期之內,對談 id 一直不改變。session 對談由伺服器端新增後,後續請求就能獲取到對談資訊,對談資訊只儲存在伺服器端。
Cookie 是儲存在使用者端上小型文字,是由伺服器端建立,然後通過響應報文的 Set-Cookie 欄位返回給使用者端。使用者端每次請求伺服器端嗎,瀏覽器都會將 Cookie 資訊傳送給伺服器端,伺服器端根據 Cookie 來識別使用者的對談資訊。Cookie 有如下幾個特點:
Session 是伺服器端儲存對談資訊,當用戶端請求伺服器端時,伺服器端會被每個使用者建立一個唯一的對談(Session id)標識,並在伺服器端設定和儲存對談資訊,並在後續的請求,可以獲取到對談資訊,主要有如下特點:
Cookie 和 Session 的主要區別:
在實際的使用場景上,Cookie 和 Session 也會結合使用,伺服器端使用Session記錄使用者的對談資訊,而將對談資訊儲存在 Cookie 中,這樣可以減少伺服器端的壓力。