效果圖網(wǎng)址大全哈爾濱seo公司
目錄
- 1,cookie 的出現(xiàn)
- 2,cookie 的組成
- 瀏覽器自動發(fā)送 cookie 的條件
- 3,設置 cookie
- 3.1,服務端設置
- 3.1,客戶端設置
- 3.3,刪除 cookie
- 4,使用流程總結
整理和測試花了很大時間,如果對你有幫助,可以點個關注哇,也有其他干貨哦~
1,cookie 的出現(xiàn)
瀏覽器和服務器之間的傳輸使用的 HTTP 協(xié)議,而它是無狀態(tài)的。也就是說,每個請求都是獨立的,服務器并不知道2次請求是否是同一個人。

為了解決這個問題,服務器想了一個辦法:
當客戶端登錄成功后,服務器會給客戶端一個令牌憑證 token;客戶端后續(xù)的請求都需要帶著這個 token 在服務器做驗證。

但用戶不可能只在一個網(wǎng)站登錄,于是客戶端會收到各個網(wǎng)站的出入證 token。所以客戶端需要一個 “卡包” 來實現(xiàn)以下功能:
- 能夠存放多個 token,token 可能來自不同的網(wǎng)站,也可能一個網(wǎng)站有多個 token。
- 能夠自動出示正確的 token,客戶端訪問不同網(wǎng)站時,會自動在請求中帶著對應的 token。
- 管理 token 的有效期,客戶端需要自動發(fā)現(xiàn)那些過期的 token 并移除。
滿足上述要求的就是 cookie,每一個 token 就是一個 cookie。
每個網(wǎng)站的 cookie 大小不超過 4kb。
2,cookie 的組成
每一個 cookie 都記錄了以下信息:(除了 key 和 value,其他非必填+順序無關)
-
key:鍵,比如表示身份編號的字符串 token
-
value:值,比如 123abc,它可以是任何字符串。
-
domain:主機(域),表示這個 cookie 是屬于哪個網(wǎng)站的,比如
www.csdn.net
?!?strong>默認值:當前主機,也就是location.host
】MDN參考 -
path:路徑,表示這個 cookie 是屬于該網(wǎng)站的哪個路徑?!?strong>默認值:實測發(fā)現(xiàn)是 cookie 所處目錄的上級目錄。比如頁面是
http://localhost:3001/a/api/login
,則 path 為/a/api
】 -
secure:是否使用安全傳輸。MDN參考
-
httpOnly:表示該 cookie 僅能用于傳輸,而客戶端通過
document.cookie
獲取的是空字符串,這對防止跨站腳本攻擊(XSS)會很有用。XSS:比如當前頁面打開 iframe,iframe 可以獲取父級的 cookie。設置 httponly 可以不允許 js 獲取來防止跨站腳本攻擊。
-
expires:過期時間,表示該 cookie 在什么時候過期。MDN 參考
-
max-age:有效期?!?strong>默認值:如果 expires 和 max-age 都不設置,則為 session,也就是會話結束后過期,大多瀏覽器關閉(注意不是標簽頁關閉)意味著會話結束。】
expires 和 max-age 一般只設置一個即可。
瀏覽器自動發(fā)送 cookie 的條件
需要同時滿足以下4個條件:
- 沒有過期。
- expires 必須是一個有效的GWT時間,格林威治標準時間字符串,比如
Fri, 22 Dec 2023 17:09:13 GMT
。到期后瀏覽器會自動刪除。
new Date().toGMTString() // Fri, 22 Dec 2023 17:09:13 GMT // 對比常見的時間格式: new Date() // Sat Dec 23 2023 01:09:13 GMT+0800 (中國標準時間)
- max-age 是相對有效期,比如
max-age=1000
,相當于設置expires=當前時間 + 1000s
- expires 必須是一個有效的GWT時間,格林威治標準時間字符串,比如
- domain 字段和這次請求的域是匹配的。
- 設置的 domain 是
csdn.net
,則可匹配的請求域有:csdn.net
、www.csdn.net
、blogs.csdn.net
等。 - 設置的 domain 是
www.csdn.net
,則只能匹配www.csdn.net
這樣的請求域。 - cookie 是不關心端口的,只要域匹配即可。
- 無效的域,瀏覽器的是不認的。比如對
https://search.jd.com/Search?keyword=xxx
網(wǎng)頁來說:
- 設置的 domain 是
【翻譯:通過 Set-Cookie 標頭設置 cookie 的嘗試被阻止,因為其域對于當前域無效】
- path 字段和這次請求的 path 也是匹配的。
/
表示匹配所有。如果是/docs
:- 匹配的路徑:
/docs
,/docs/
,/docs/Web/
,/docs/Web/HTTP
- 不匹配的路徑:
/
,/docsets
,/fr/docs
- 匹配的路徑:
- secure 字段驗證。設置該字段,則請求協(xié)議必須是 https(否則不發(fā)送 cookie);不設置則請求協(xié)議可以是 https 或 http。
瀏覽器會將符合條件的 cookie,自動添加到請求頭 Cookie 中。下圖可以看到有3個滿足的 cookie,以 ;
分隔。
3,設置 cookie
cookie 是保存在瀏覽器端的,有2種設置模式:
- 服務器設置:通過設置響應頭
set-cookie: 123abc
,瀏覽器會自動保存在 “卡包” 中。查看方式:控制臺–>Application–> Storage–>Cookies - 瀏覽器設置:這種情況比較少見。舉例:用戶關閉了廣告時勾選了【不喜歡】或其他原因,就可以把這種小信息直接通過 js 保存到 cookie 中。后續(xù)請求服務器時,服務器會根據(jù)這個信息調(diào)整廣告投放。
3.1,服務端設置
可在一次響應中設置多個 cookie。格式如下:
鍵=值; path=?; domain=?; expires=?; max-age=?; secure; httponly
舉例:
// 服務端
const Koa = require("koa");
const Router = require("koa-router");
const { bodyParser } = require("@koa/bodyparser");const app = new Koa();
const router = new Router();router.post("/api/login", (ctx) => {const { name, pwd } = ctx.request.body;if (name === "下雪天的夏風" && pwd === "123") {ctx.set("set-cookie", 'token=aaa; domain=localhost; max-age=3600;secure; httponly');ctx.body = "登錄成功";} else {ctx.body = {code: 500,msg: "用戶名或密碼錯誤",};}
});router.get("/api/home", (ctx) => {ctx.body = "home";
});app.use(bodyParser()).use(router.routes());
app.listen(3000);
<!-- 前端 -->
<form action="http://localhost:3000/api/login" method="post" target="_blank"><input type="text" name="name" /><input type="password" name="pwd" /><button>提交</button>
</form>
form 表單發(fā)送請求登錄成功后,會自動跳轉到頁面 http://localhost:3000/api/login
,可以看到 cookie 已經(jīng)設置了:
- 注意到
path
的默認值是 cookie 所處目錄的上級目錄。 - expires/max-age 的時間格式保存為 ISO國際標準時間
new Date() // Sat Dec 23 2023 01:27:53 GMT+0800 (中國標準時間)
new Date().toISOString() // 2023-12-22T17:27:53.738Z
new Date().toGMTString() // Fri, 22 Dec 2023 17:27:53 GMT
再次訪問 http://localhost:3000/api/home
時,會發(fā)現(xiàn)請求頭中自動帶上了 cookie:
3.1,客戶端設置
格式和在服務端相同,只是 httponly
字段無效。因為該字段本來就是限制在客戶端訪問的,客戶端設置它沒有意義。
document.cookie = 'token=aaa; domain=localhost;secure;httponly'
3.3,刪除 cookie
可以修改 cookie 的過期時間即可:max-age=-1
。瀏覽器會自動刪除。
可以讓服務器響應一個同樣的 domain、同樣的 path、同樣的 key,只是時間過期的 cookie 即可。
以上面的例子來說,設置如下:
ctx.set("set-cookie", 'token=aaa; domain=localhost; max-age=-1');
或客戶端刪除:
document.cookie = 'token=aaa; domain=localhost; max-age=-1'
注意:無論是修改還是刪除,都需要注意 domain 和 path,因為可能存在 domain 和 path 不同但 key 相同的 cookie。
4,使用流程總結
登錄 / 注冊請求:
- 瀏覽器發(fā)送用戶名和密碼到服務器。
- 服務器驗證通過后,在響應頭中設置 cookie,附帶登錄認證信息(一般為 jwt)。
- 瀏覽器收到 cookie 保存下來。
后續(xù)請求,瀏覽器會自動將符合的 cookie 附帶到請求中;服務器驗證 cookie 后,允許其他操作完成業(yè)務流程。
以上。