如何讀取 Cookie ?
栏目: JavaScript · 发布时间: 5年前
内容简介:當我們使用VS Code 1.34.0Quokka 1.0.216
當我們使用 document.cookie()
讀取 Cookie 時,回傳為 String,我們希望提供 Key 讀取其 Value,這常見的需求該如何實現呢 ? 本文分別使用 Imperative、Functional 與 Maybe 三種方式實現。
Version
VS Code 1.34.0
Quokka 1.0.216
Ramda 0.26.1
Cookie
let readCookie = () => { let data = document.cookie.split('; ').slice(0, -2); console.log(getCookie('firstName')(data)); };
實務上要使用 document.cookie
去讀取 cookie,但讀出來為以下格式:
firstName=Sam; lastName=Xiao; _ga=GA1.1.320322304.1546312556; Hm_lvt_47acec2d282c3986f1b600abdc11c7ab=155525178
倒數第二個 ;
之後的資訊並不是我們要的,所以先 split()
成 array 後,用 slice()
取得不含倒數兩個 element 的新 array,最後再傳入 getCookie()
,根據 key 取得 value。
Imperative
let data = [ 'firstName=Sam', 'lastName=Xiao' ]; // getCookie :: String -> [String] -> String let getCookie = key => arr => { for(let i = 0; i < arr.length; i++) { let tuple = arr[i].split('='); if (tuple[0] === key) return tuple[1]; } return ''; }; console.log(getCookie('firstName')(data)); console.log(getCookie('lastName')(data)); console.log(getCookie('age')(data));
data
為根據 document.cookie()
所整理過的 string。
我們希望當傳入 key 時, getCookie()
回傳 value。
第 8 行
for(let i = 0; i < arr.length; i++) {
Imperative 會使用 for
loop 一個一個找。
第 9 行
let tuple = s.split('=');
Array 中的 string 形式為 firstName=Sam
,可再使用 split()
拆成 array,因為很類似 tuple,變數姑且命名為 tuple
。
tuple
當然是很糟糕的命名,應該取一個有意義的變數名稱
第 10 行
if (tuple[0] === key) return tuple[1];
tuple[0]
即為 key,而 tuple[1]
為 value,因此可直接使用 if
判斷。
Imperative 會充斥著 中繼變數
,然後就開始為 變數命名
傷腦筋,要如何使變數可讀性高又有意義,但畢竟我們在乎的是結果,這些中繼變數真的需要嗎 ? 是值得深思的問題
13 行
return '';
若傳入的 key 不存在,則回傳 empty string,避免產生 undefined
。
Functional
import { pipe, compose, split, converge, nth, objOf, map, find, propOr, prop, isNil, complement } from 'ramda'; let data = [ 'firstName=Sam', 'lastName=Xiao' ]; // strToObj :: String -> Object let strToObj = pipe( split('='), converge(objOf, [nth(0), nth(1)]) ); // isNotNil :: * -> Boolean let isNotNil = complement(isNil); // getCookie :: String -> [String] -> String let getCookie = key => pipe( map(strToObj), find(compose(isNotNil, prop(key))), propOr('', key) ); console.log(getCookie('firstName')(data)); console.log(getCookie('lastName')(data)); console.log(getCookie('age')(data));
17 行
// getCookie :: String -> [String] -> String let getCookie = key => pipe( map(strToObj), find(compose(isNotNil, prop(key))), propOr('', key) );
FP 不會使用 for
loop 處理,可由 pipe()
清楚看出演算法流程:
- 先使用
map()
將 array 內的 string 轉成 object - 再使用
find()
搜尋 array 中每個 object,找到就傳回 object,否則傳回undefined
- 最後使用
propOr()
根據 key 取得 value
其中將 string 轉成 object,是想借助 Ramda 對 object 支援豐富 function。
可以看出 FP 解決問題方式是將問題最小化切割,然後各個擊破,與 Imperative整體思考方式不同
第 8 行
// strToObj :: String -> Object let strToObj = pipe( split('='), converge(objOf, [nth(0), nth(1)]) );
split() objOf()
20 行
find(compose(isNotNil, prop(key)))
使用 find()
根據 key 找尋 value,其 predicate 為 (a -> Boolean)
,而 prop()
回傳為 a | Undefined
,因此組合 isNotNil()
使其轉成 boolean。
14 行
// isNotNil :: * -> Boolean let isNotNil = complement(isNil);
Ramda 並沒有提供 isNotNil()
,須自行組合,也可使用 compose(not, isNil)
。
21 行
propOr('', key)
由於 find()
可能回傳 undefined
,所以特別使用了 propOr()
處理。
我們可發現 FP 完全 沒有
中繼變數,所以再也不必為了變數命名而傷透腦筋
Maybe
import { pipe, compose, split, converge, nth, objOf, map, find, prop, isNil, complement } from 'ramda'; import { prop as prop_ } from 'crocks'; let data = [ 'firstName=Sam', 'lastName=Xiao' ]; // strToObj :: String -> Object let strToObj = pipe( split('='), converge(objOf, [nth(0), nth(1)]) ); // isNotNil :: * -> Boolean let isNotNil = complement(isNil); // getCookie :: String -> [String] -> Maybe String let getCookie = key => pipe( map(strToObj), find(compose(isNotNil, prop(key))), prop_(key), ); console.log(getCookie('firstName')(data).option('N/A')); console.log(getCookie('lastName')(data).option('N/A')); console.log(getCookie('age')(data).option('N/A'));
Ramda 的 find()
唯一缺點就是回傳 undefined
,因此我們必須小心翼翼地使用 propOr()
處理,但這有幾個缺點:
-
undefined
並非邏輯的一部分,是為了find()
而處理 - 若一不小心使用了
prop()
,就可能回傳undefined
- 目前我們使用
propOr('', key)
,也就是undefined
時回傳 empty string,但若使用端想自行決定undefined
的 string 呢 ?
比較好的方式是回傳 Maybe
,由使用端決定 undefined
該如何處理。
21 行
find(compose(isNotNil, prop(key))), prop_(key),
由於要回傳 Maybe
,改用 Crocks 的 prop()
,而不是 Ramd 的 prop()
,因為 Crocks 很多 function 名稱與 Ramda 一樣,差異只在於回傳 Maybe
,因此 Crocks 所提供的同名 function 一律以 _
postfix 表示。
26 行
console.log(getCookie('firstName')(data).option('N/A')); console.log(getCookie('lastName')(data).option('N/A')); console.log(getCookie('age')(data).option('N/A'));
由於 getCookie()
回傳 Maybe
,必須透過 option()
將 Maybe
轉回 string。
若 undefined
時想顯示 N/A
,可一併傳進 option()
。
使用 Maybe
後, undefined
改由使用端處理, getCookie()
可專心處理正常邏輯,不必再為了 undefined
分心,程式碼邏輯也更清楚
以上所述就是小编给大家介绍的《如何讀取 Cookie ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Impractical Python Projects
Lee Vaughan / No Starch Press / 2018-11 / USD 29.95
Impractical Python Projects picks up where the complete beginner books leave off, expanding on existing concepts and introducing new tools that you’ll use every day. And to keep things interesting, ea......一起来看看 《Impractical Python Projects》 这本书的介绍吧!
HTML 编码/解码
HTML 编码/解码
正则表达式在线测试
正则表达式在线测试