我最新最全的文章都在南瓜慢說 www.pkslow.com,歡迎大家來喝茶!

1 簡介

HTTP Cookies是伺服器傳送到使用者瀏覽器並儲存在本地的一小塊資料,它會在瀏覽器下次向同一伺服器再發起請求裡被攜帶併發送到伺服器上。

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

  • 會話狀態管理(如使用者登入狀態、購物車、遊戲分數或其它需要記錄的資訊)
  • 個性化設定(如使用者自定義設定、主題等)
  • 瀏覽器行為跟蹤(如跟蹤分析使用者行為等)

2 Chrome檢視Cookies

通過Chrome強大的工具,可以直接檢視Cookies,如下面所示:

3 Cookies的屬性

3.1 限制訪問Cookie

3.1.1 Secure標記

標記為SecureCookie只能被HTTPS協議加密過的請求傳送給服務端,使用HTTP是不行的,但localhost除外。

3.1.2 HttpOnly標記

標記為HttpOnlyCookie只能通過HTTP傳輸,而無法在客戶端本地通過JavaScript訪問。這有助於緩解跨站點指令碼(XSS)攻擊。

3.2 Cookie的作用域

3.2.1 Domain屬性

用於指定哪些主機可以接受Cookie,如果不指定,預設為Origin,不包含子域名。如果指定了Domain,則一般包含子域名。所以,指定Doain,限制其實更少。

比如,如果Domain=pkslow.com,那blog.pkslow.com也可以接受。

3.2.2 Path屬性

指定哪些路徑可以接受Cookie,子路徑也會匹配。

比如,如果Path=/post,那以下都可以匹配:

  • /post
  • /post/1
  • /post/1/update

4 Springboot操作Cookies

4.1 獲取

4.1.1 通過註解@CookieValue

@RequestMapping("/hello")
public String hello(@CookieValue("foo") String fooCookie) {
// ...
}

4.1.2 通過工具類WebUtils的getCookie方法

public static Cookie getCookie(HttpServletRequest request, String name) {
Assert.notNull(request, "Request must not be null");
Cookie[] cookies = request.getCookies();
if (cookies != null) {
Cookie[] var3 = cookies;
int var4 = cookies.length; for(int var5 = 0; var5 < var4; ++var5) {
Cookie cookie = var3[var5];
if (name.equals(cookie.getName())) {
return cookie;
}
}
} return null;
}

4.1.3 WebFlux的ServerWebExchange獲取

HttpCookie value = exchange.getRequest().getCookies().getFirst("foo");

4.2 返回

與獲取反著來就行了,獲取是從Request中拿資料;傳送就是把資料放到Response中去。

response.addCookie();

5 傳送Cookie

5.1 瀏覽器

瀏覽器會根據規則傳送,這個不用開發人員自己處理。

5.2 Postman

Postman可以在這裡設定:

5.3 curl命令

curl -v --cookie "key1:value1;key2:value2;" http://localhost:8080/

5.4 JavaScript fetch方法

credentialsRequest介面的只讀屬性,用於表示使用者代理是否應該在跨域請求的情況下從其他域傳送cookies。這與XHR的withCredentials 標誌相似,不同的是有三個可選值(後者是兩個):

  • omit: 從不傳送cookies.
  • same-origin: 只有當URL與響應指令碼同源才傳送 cookies、 HTTP Basic authentication 等驗證資訊.(瀏覽器預設值,在舊版本瀏覽器,例如safari 11依舊是omit,safari 12已更改)
  • include: 不論是不是跨域的請求,總是傳送請求資源域在本地的 cookies、 HTTP Basic authentication 等驗證資訊.

為了讓瀏覽器傳送包含憑據的請求(即使是跨域源),要將credentials: 'include'新增到傳遞給 fetch()方法的init物件。

fetch('https://example.com', {
credentials: 'include'
})

如果你只想在請求URL與呼叫指令碼位於同一起源處時傳送憑據,請新增 credentials: 'same-origin'

// The calling script is on the origin 'https://example.com'

fetch('https://example.com', {
credentials: 'same-origin'
})

要改為確保瀏覽器不在請求中包含憑據,請使用 credentials: 'omit'

fetch('https://example.com', {
credentials: 'omit'
})

6 總結

開發中遇到了一些Cookies問題,整理了一下相關的知識點。


歡迎關注微信公眾號<南瓜慢說>,將持續為你更新...

多讀書,多分享;多寫作,多整理。