一日一技:前端與后端都是怎么讀寫(xiě) Cookies 的?
大家應(yīng)該看過(guò)一些網(wǎng)站,在第一次訪問(wèn)的時(shí)候,它會(huì)彈出一些小提示或者操作指導(dǎo),類(lèi)似于下圖所示:
當(dāng)我關(guān)閉了這個(gè)提示以后,接下來(lái)它都不會(huì)彈出來(lái)。當(dāng)我關(guān)閉了瀏覽器再打開(kāi),它也不會(huì)再?gòu)棾鰜?lái)。但是,大家觀察截圖右上角,可以看到我并沒(méi)有登錄,那么網(wǎng)站是怎么“記住”了我關(guān)閉這個(gè)提示的呢?實(shí)際上是通過(guò) Cookies 來(lái)記錄的。當(dāng)我點(diǎn)擊X 關(guān)閉這個(gè)提示的時(shí)候,網(wǎng)站的JavaScript 會(huì)往 Cookies 里面寫(xiě)入一條標(biāo)記。當(dāng)我們每次打開(kāi)這個(gè)網(wǎng)站新的頁(yè)面的時(shí)候,它都會(huì)判斷一下 Cookies 里面有沒(méi)有這個(gè)標(biāo)記。如果沒(méi)有這個(gè)標(biāo)記,就彈出提示。如果有這個(gè)標(biāo)記,就不彈出。
Cookies 本質(zhì)上是一個(gè)長(zhǎng)字符串,里面使用分號(hào)隔開(kāi)了很多項(xiàng),每一項(xiàng)由 Key 和 Value 組成,叫做一個(gè) Cookie。
要不要彈出提示的開(kāi)關(guān)在這里
當(dāng)我們要往 Cookies 里面添加一條 Cookie 有兩種常用方式:使用 JavaScript 或者通過(guò)后端設(shè)置。
使用 JavaScript 讀寫(xiě) Cookies
讀取當(dāng)前所有的 Cookies,可以使用代碼:
- document.cookie
運(yùn)行效果如下圖所示:
需要注意的是,如果你要判斷某個(gè)鍵值是不是在 Cookies 里面,那么你需要做字符串匹配。這不能像 Object 一樣直接根據(jù) Key 去找 Value 或者判斷 Key 在不在里面。
要寫(xiě)入一條 Cookie,我們可以使用代碼:
- document.cookie = 'key=value'
例如:
這里我們使用document.cookie=新的值,看起來(lái)像是覆蓋了整個(gè) Cookies,但實(shí)際上并不是這樣。如果你新增的 key 跟已有的相同,那么會(huì)覆蓋原有的這一個(gè) Cookie的值,不影響其他的 Cookie;如果你新增的 key 不在原來(lái)的 Cookies 里面,那么它將會(huì)被添加到末尾。
使用 FastAPI讀寫(xiě) Cookies
還有一種方式是在后端設(shè)置 Cookies,我們以 FastAPI 為例來(lái)進(jìn)行演示:
首先是向?yàn)g覽器寫(xiě)入 Cookies,使用的代碼如下:
- from fastapi import FastAPI, Response
- app = FastAPI()
- @app.get('/')
- def index(response: Response, name: str = ''):
- if not name:
- name = 'kingname'
- response.set_cookie('name', name)
- return {'success': True, 'msg': '網(wǎng)站正常運(yùn)行'}
這段代碼的關(guān)鍵是路由函數(shù)的第一個(gè)參數(shù)response: Response。它的值是一個(gè)Response對(duì)象。我們只需要調(diào)用這個(gè)對(duì)象的.set_cookie方法,就能把自定義的 Cookie 添加進(jìn)去。需要注意的是,你不需要主動(dòng)返回這個(gè) response 對(duì)象。
運(yùn)行效果如下圖所示,分別演示了有URL參數(shù)和沒(méi)有URL參數(shù)的情況。
沒(méi)有 URL 參數(shù)
有 URL 參數(shù)
至于讀取 Cookies 也非常簡(jiǎn)單,并且還可以根據(jù) Key 指定要哪幾項(xiàng):
- from typing import Optional
- from fastapi import FastAPI, Cookie
- app = FastAPI()
- @app.get('/')
- def index(name: str = '', info: Optional[str] = Cookie(None)):
- if not name:
- name = 'kingname'
- msg = f'{name} 你好,你的 Cookies中的info字段的值是: {info}'
- return {'success': True, 'msg': msg}
我們注意到參數(shù)中有一項(xiàng)叫做info,這個(gè)參數(shù)名字就對(duì)應(yīng)了 Cookies 中某一項(xiàng)的 Key。只有這個(gè) Key 存在,這個(gè) info 參數(shù)才會(huì)有值,否則它就是 None。
運(yùn)行效果如下圖所示:
如果你想從 Cookies 中拿多項(xiàng),那么你可以多寫(xiě)幾個(gè)參數(shù):
- @app.get('/')
- def index(name: str = '', info: Optional[str] = Cookie(None), is_new_user: Optional[bool] = Cookie(False)):
- if not name:
- name = 'kingname'
- msg = f'{name} 你好,你的 Cookies中的info字段的值是: {info}, 是新用戶嗎:{is_new_user}'
- return {'success': True, 'msg': msg}
運(yùn)行效果如下圖所示:
總結(jié)
無(wú)論使用前端方式還是后端方式,你都可以通過(guò)在 Cookies 里面儲(chǔ)存一些信息,來(lái)實(shí)現(xiàn)某些開(kāi)關(guān)或者記錄一些信息。
本文轉(zhuǎn)載自微信公眾號(hào)「未聞Code」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系未聞Code公眾號(hào)。