1.cookie
是由W3C組織提出,最早由Netscape社區(qū)發(fā)展的一種機(jī)制。由于HTTP是一種無狀態(tài)的協(xié)議,服務(wù)器單從網(wǎng)絡(luò)連接上無從知道客戶身份。怎么辦呢?就給客戶端們頒發(fā)一個(gè)通行證吧,每人一個(gè),無論誰訪問都必須攜帶自己通行證。這樣服務(wù)器就能從通行證上確認(rèn)客戶身份了。這就是Cookie的工作原理。
簡(jiǎn)單說cookie會(huì)話跟蹤技術(shù)
在一次會(huì)話從開始到結(jié)束的整個(gè)過程中,全程跟蹤記錄客戶端的狀態(tài),例如是否登錄,購(gòu)物車信息, 是否已經(jīng)下載,是否已經(jīng)點(diǎn)贊,視頻播放進(jìn)度等
1.1. cookie的作用與特性
cookie是存儲(chǔ)在瀏覽器中的緩存信息
1.1.1 作用:
- 登錄記錄
- 多個(gè)頁面的數(shù)據(jù)傳遞
- 保存用戶信息
1.1.2 完整的格式
name=value;[expires=date];[path=path]
1.1.3 特點(diǎn):
- 存值不大(最大可以存4kb)
- 每個(gè)域名下最多存儲(chǔ)50條數(shù)據(jù)(不同瀏覽器會(huì)有不同)
- 可以自己設(shè)置過期時(shí)間
- 具有不可跨域性
1.1.4 中文的編碼
中文與英文字符不同,中文屬于Unicode字符,在內(nèi)存中占2個(gè)字符(4個(gè)字節(jié)),而英文屬于ASCII字符,內(nèi)存中只占2個(gè)字節(jié)。Cookie中使用Unicode字符時(shí)需要對(duì)Unicode字符進(jìn)行編碼,否則會(huì)亂碼。
所以cookie直接存中文可能會(huì)出現(xiàn)亂碼
encodeURIComponent 將中文編譯成對(duì)應(yīng)的字符
decodeURIComponent 將對(duì)應(yīng)的字符轉(zhuǎn)為中文
這兩個(gè)方法互逆,都是window上帶的方法,可以直接用
<script>
let str = '心存美好'
let aa =encodeURIComponent(str);
console.log(aa);
let bb = decodeURIComponent(aa)
console.log(bb)
</script>
1.2. 設(shè)置cookie
我們可以先檢查緩存cookie
console.log(document.cookie)//實(shí)際上設(shè)置cookie之前是沒有cookie值的
設(shè)置cookie
document.cookie = 'name=wuwei'
<script>
//檢查/獲取本地cookie
console.log(document.cookie)
//設(shè)置本地cookie
document.cookie = 'name=心存美好' //表示一條cookie記錄 有屬性和值
document.cookie = 'age=18';
document.cookie = 'hooby=sing'
//控制臺(tái)-->Application-->Storage(左側(cè))-->Cookies-->127.0.0.1:5500服務(wù)中可以看到記錄
</script>
默認(rèn)cookie的結(jié)束時(shí)間是關(guān)閉瀏覽器的時(shí)候
1.3.. 設(shè)置過期時(shí)間
設(shè)置cookie的過期時(shí)間使用expires
<script> // console.log(new Date)//時(shí)間對(duì)象格式 // console.log(new Date().toGMTString())//字符串時(shí)間格式 let date = new Date(new Date().getTime() + 3000);//用getTime先轉(zhuǎn)成毫秒數(shù),加上3000ms,再轉(zhuǎn)成時(shí)間 document.cookie = `name=美好;expires=${date.toGMTString()}` //cookie時(shí)間過期會(huì)自動(dòng)刪除cookie,過期就訪問不到 console.log(date) </script>
<script>
//max-age設(shè)置cookie時(shí)間
document.cookie = `name=美好;max-age=${3}`//單位是s,超過時(shí)間自動(dòng)刪除也可以寫成`name=美好;max-age=3`
</script>
過期時(shí)間不能小于當(dāng)前時(shí)間,因?yàn)樾∮诋?dāng)前時(shí)間,說明cookie已經(jīng)過期了
var date = new Date(new Date().getTime() -1) ;
所謂的刪除cookie 就是讓cookie 已經(jīng)到達(dá)過期時(shí)間, cookie一旦過期, 會(huì)自動(dòng)刪除
<script>
document.cookie = 'name=美好'
del.onclick = function () {
let date = new Date(new Date().getTime() - 10);//設(shè)置成-10就會(huì)立即過期//刪除方法一
document.cookie = `name=美好;expires=${date.toGMTString()}`
// document.cookie = `name=美好;max-age = ${0}`//刪除方法二
}
</script>
1.4. 設(shè)置多個(gè)cookie
var date = new Date(new Date().getTime() + 30 * 60 * 1000);
document.cookie = 'name=wuwei;expires =' + date.toGMTString();
document.cookie = 'pwd=w123456;expires =' + date.toGMTString();
console.log(document.cookie)
1.5. 封裝設(shè)置cookie
1.5.1 設(shè)置cookie
// 封裝的設(shè)置一個(gè)cookie的函數(shù)
function setCookie(data){
var date = new Date(new Date().getTime() + data.time * 60* 1000).toGMTString();
document.cookie = data.name +'='+ data.value+';expires='+date
}
setCookie({
name:'zhangsan',
value:18,
time:5
})
// 設(shè)置單個(gè)cookie
function setCookie(name,value,{expires, path, domain, secure}){
var cookieStr = encodeURIComponent(name) + '=' + encodeURIComponent(value)
if(expires){
cookieStr += ';expries=' + afterOfDate(expires)
}
if(path){
cookieStr += ";path=" + path
}
if(domain){
cookieStr += ";path=" + domain
}
if(secure){
cookieStr += ";secure"
}
document.cookie = cookieStr
}
function afterOfDate(n){
var d = new Date()
var day = d.getDate();
d.setDate(n + day)
return d
}
<script>
// 封裝cookie設(shè)置
function setCookie(data) {
let date = new Date(new Date().getTime() + data.expires);
let cookie = `${data.name}=${data.value};data.expires=${date.toGMTString()}`
if (data.path) {//如果存在這個(gè)屬性就加上
cookie += ";path=" + path
}
if (data.domain) {
cookie += ";domain=" + domain
}
if (data.secure) {
cookie += ";secure" + secure
}
document.cookie = cookie;
}
setCookie({
name: 'age',//cookie字段名
value: 18,//字段值
expires: 3000,//過期時(shí)間
path: '/',
})
</script>
1.5.2 封裝獲取getCookie
function getCookie(name){
var cookieStr = decodeURIComponent(document.cookie)
var start = cookieStr.indexOf(name + '=')
if(start == -1){
return null
}else{
// 查詢結(jié)束的位置
var end = cookieStr.indexOf(";", start)
if(end == -1){
end = cookieStr.length
}
var str = cookieStr.substring(start,end)
return str.split("=")[1]
}
}
1.5.3 封裝刪除cookie
清除cookie
思路就是將cookie時(shí)間設(shè)置為已經(jīng)過期的時(shí)間瀏覽器會(huì)自動(dòng)清楚過期的cookie
function removeCookie(name){
document.cookie = encodeURIComponet(name) + "=;expires=" + new Date(0)
}
1.6. 封裝設(shè)置多個(gè)cookie
function setCookie(data){
data.forEach((item,index)=>{
var date = new Date(new Date().getTime() + item.time * 60* 1000).toGMTString();
document.cookie = item.name +'='+ item.value+';expires='+date
})
}
setCookie([
{
name:'zhangsan',
value:18,
time:5
},{
name:'lisi',
value:30,
time:10
},{
name:'wangwu',
value:41,
time:10
}
])
1.7. 設(shè)置所有cookie常用的屬性
| 屬性 | 描述 |
|---|---|
| name | 該Cookie的名稱。Cookie一旦創(chuàng)建,名稱便不可更改 |
| value | 該Cookie的值。如果值為Unicode字符,需要為字符編碼。 |
| expires | 設(shè)置cookie的過期時(shí)間使用expires(確定的時(shí)間) |
| maxAge | max-age用秒來設(shè)置cookie的生存期(5*24*60*60)
|
| path | 該Cookie的使用路徑 |
| domain | 可以訪問該Cookie的域名。(localhost) |
| secure | 該Cookie是否僅被使用安全協(xié)議傳輸。安全協(xié)議。默認(rèn)為false<br />如果不設(shè)置字段 cookie 可以通過http,https 協(xié)議加載設(shè)置<br />如果設(shè)置這個(gè)字段, 那么只能通過https協(xié)議才能設(shè)置成 |
| HTTP-Only | HTTP-Only 背后的意思是告之瀏覽器該 cookie 絕不能通過 JavaScript 的 document.cookie屬性訪問。<br />默認(rèn)是false(沒有值),前端就可以訪問。如果值為true,則只有后端可以訪問前端不可以訪問。<br />控制臺(tái)中雙擊就可以true、false切換 |
2.本地存儲(chǔ)
本地存儲(chǔ)是HTML5中新增的特性,用來解決cookie存儲(chǔ)空間不足的問題
1、概述:
對(duì)于Web Storage來說,實(shí)際上是Cookies存儲(chǔ)的進(jìn)化版。
背熟這句口訣:“兩個(gè)接口,四個(gè)函數(shù)”。
2、口訣:
(1)兩個(gè)接口:分別是sessonStorage(臨時(shí)存儲(chǔ))和localStorage(本地存儲(chǔ))
(2)四個(gè)函數(shù):分別是setItem、getItem、removeItem和clear。(設(shè)置、獲取、刪除、)
2.1. Storage
2.1.1 sessionStorage
session臨時(shí)回話,從頁面打開到頁面關(guān)閉的時(shí)間段
窗口的臨時(shí)存儲(chǔ),頁面關(guān)閉,本地存儲(chǔ)消失
臨時(shí)存儲(chǔ)就是存儲(chǔ)一下,其他頁面并不會(huì)共享
<body>
<!-- 本地存儲(chǔ) -->
<input type="text" name="" id="text">
<button id="addData">設(shè)置</button>
<button id="addData2">設(shè)置2</button>
<button id="addData3">設(shè)置3</button>
<button id="getData">獲取</button>
<button id="removeData">刪除</button>
<button id="clearData">清空</button>
<div id="box"></div>
<div id="box3"></div>
<!--獲取的數(shù)據(jù)內(nèi)容添加到這里 -->
<script>
//查看臨時(shí)會(huì)話 控制臺(tái)--》Application-->storage-->sesssion Storage--->127.0.0.1:5500。頁面關(guān)閉時(shí)數(shù)據(jù)就消失
addData.onclick = function () {//設(shè)置
console.log(11);
if (text.value.trim()) {//點(diǎn)擊設(shè)置,判斷是否有值
sessionStorage.setItem('name', text.value)//有值設(shè)置input的值,設(shè)置后在Application-->storage-->sesssion Storage--->127.0.0.1:5500就會(huì)看到,要?jiǎng)h除默認(rèn)的值
} else {
alert('請(qǐng)輸入內(nèi)容')//點(diǎn)擊設(shè)置,為空出現(xiàn)彈框
}
}
addData2.onclick = function () {//設(shè)置的另一個(gè)age值,字段名和字段值一一對(duì)應(yīng)
console.log(11);
if (text.value.trim()) {
sessionStorage.setItem('age', text.value)
} else {
alert('請(qǐng)輸入內(nèi)容')
}
}
addData3.onclick = function () {//設(shè)置的另一個(gè)age值,字段名和字段值一一對(duì)應(yīng)
console.log(11);
if (text.value.trim()) {
sessionStorage.setItem('user', JSON.stringify({
name: '張五', age: '50'
}))//即使存儲(chǔ)的是對(duì)象,控制臺(tái)里也會(huì)自動(dòng)轉(zhuǎn)成字符串[object,Object]。要使用JSON.stringify轉(zhuǎn)成字符串才是對(duì)象字符串
} else {
alert('請(qǐng)輸入內(nèi)容')
}
}
getData.onclick = function () {
console.log(22)
let data = sessionStorage.getItem('name')//傳獲取的字段名,要獲取name字段名
box.innerHTML = data;//點(diǎn)擊‘獲取’就將input里的值取出來了,放到頁面上了
let data3 = sessionStorage.getItem('user')
console.log(typeof data3)
console.log(data3)//這時(shí)是字符串
console.log(JSON.parse(data3))//通過JSON.parse轉(zhuǎn)成了對(duì)象,點(diǎn)開控制臺(tái)原型可以看到
box3.innerHTML = data3;
}
removeData.onclick = function () {
console.log(33)
sessionStorage.removeItem('name')
}
clearData.onclick = function () {
console.log(44);
sessionStorage.clear()//全部干掉了
}
// 特性
// 1.sessionStorage是臨時(shí)會(huì)話,如果頁面關(guān)閉數(shù)據(jù)自動(dòng)刪除
// 2.數(shù)據(jù)不共享,即使同一個(gè)網(wǎng)站同一個(gè)頁面數(shù)據(jù)也不共享。
// 3.存儲(chǔ)的數(shù)據(jù)都是字符串,如果想要存對(duì)象或數(shù)組,先使用JSON轉(zhuǎn)成字符串
</script>
</body>
JSON是js內(nèi)置的一個(gè)對(duì)象。JSON是有固定格式的字符串。JSON里面的字段必須要雙引。
// JSON.stringify() 把對(duì)象類型轉(zhuǎn)成字符串
// JSON.parse() 把字符串解析成對(duì)象
let obj = { //這個(gè)數(shù)據(jù)傳給后端時(shí),后端不一定識(shí)別,但字符串是所有瀏覽器都能識(shí)別的,通過JSON.stringify()轉(zhuǎn)成字符串
name: '張三',
age: 19
}
let aa = JSON.stringify(obj) //對(duì)象轉(zhuǎn)字符串
let bb = JSON.parse(aa)//字符串解析成對(duì)象
console.log(typeof aa)
console.log(typeof bb)
// JSON對(duì)象:對(duì)象格式的JSON
// JSON數(shù)組:數(shù)組格式的JSON
let arr = [10, 20, 30, { name: '張三' }]
let arrJSON = JSON.stringify(arr)
console.log(arrJSON)
console.log(typeof arrJSON)//數(shù)組格式的JSON
console.log(JSON.parse(arrJSON))//此時(shí)又將json轉(zhuǎn)成數(shù)組了
// JSON在js中外部需要加單引號(hào)'',JSON單獨(dú)創(chuàng)建xxx.json文件時(shí)就不需要單引號(hào)了,直接在文件里寫內(nèi)容就可以{"":"","":""},json文件里也都需要雙引號(hào)
2.1.2 localStorage
域內(nèi)安全、永久保存。瀏覽器不刪除,會(huì)一直存儲(chǔ)著數(shù)據(jù)。即客戶端或?yàn)g覽器中來自同一域名的所有頁面都可訪問localStorage數(shù)據(jù)且數(shù)據(jù)除了刪除否則永久保存,但客戶端或?yàn)g覽器之間的數(shù)據(jù)相互獨(dú)立。
永久存儲(chǔ)(可以手動(dòng)刪除數(shù)據(jù))
多個(gè)頁面可以共享
<body>
<!-- 本地存儲(chǔ) -->
<input type="text" name="" id="text">
<button id="addData">設(shè)置</button>
<button id="addData2">設(shè)置2</button>
<button id="addData3">設(shè)置3</button>
<button id="getData">獲取</button>
<button id="removeData">刪除</button>
<button id="clearData">清空</button>
<div id="box"></div>
<div id="box3"></div>
<script>
//此時(shí)打開控制臺(tái) --》Application-->localStorage中沒有數(shù)據(jù)。
//輸入數(shù)據(jù)后--》點(diǎn)設(shè)置,控制臺(tái)中就有數(shù)據(jù)了。
//此時(shí)再開啟新頁面,控制臺(tái)中剛剛設(shè)置的數(shù)據(jù)依然存在
addData.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('name', text.value)
} else {
alert('請(qǐng)輸入內(nèi)容')
}
}
addData2.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('age', text.value)
} else {
alert('請(qǐng)輸入內(nèi)容')
}
}
addData3.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('user', JSON.stringify({
name: '張五', age: '50'
}))
} else {
alert('請(qǐng)輸入內(nèi)容')
}
}
getData.onclick = function () {
console.log(22)
let data = localStorage.getItem('name')
box.innerHTML = data;
}
removeData.onclick = function () {
console.log(33)
localStorage.removeItem('name')
}
clearData.onclick = function () {
console.log(44);
localStorage.clear()
}
</script>
</body>
2.2. Storage的特點(diǎn)
- 永久存儲(chǔ)
- 存儲(chǔ)量限制 ( 5M ) 客戶端微型數(shù)據(jù)庫
- 客戶端完成,不會(huì)請(qǐng)求服務(wù)器處理
- sessionStorage數(shù)據(jù)是不共享、 localStorage共享
- 瀏覽器不統(tǒng)一,并且在IE8以下不兼容
- 儲(chǔ)存的值限定是字符串類型,需要我們通過JSON 對(duì)象去轉(zhuǎn)換
- 存儲(chǔ)內(nèi)容多的話會(huì)消化內(nèi)容空間,會(huì)導(dǎo)致變卡
2.3. Storage API
2.3.1 setItem(鍵名,鍵值):
設(shè)置數(shù)據(jù),(key,value)類型,類型都是字符串
可以用獲取屬性的形式操作
在本地客戶端存儲(chǔ)一個(gè)字符串類型的數(shù)據(jù),其中,第一個(gè)參數(shù)“鍵名”代表了該數(shù)據(jù)的標(biāo)識(shí)符,而第二個(gè)參數(shù)“鍵值”為該數(shù)據(jù)本身。
例如:
localStorage.setItem("name", "wuwei");
2.3.2 getItem():
讀取已存儲(chǔ)在本地的數(shù)據(jù),通過鍵名作為參數(shù)讀取出對(duì)應(yīng)鍵名的數(shù)據(jù)。如:
獲取數(shù)據(jù),通過key來獲取到相應(yīng)的value
var data = localStorage.getItem("name");
2.3.3 removeItem():
移除已存儲(chǔ)在本地的數(shù)據(jù),通過鍵名作為參數(shù)刪除對(duì)應(yīng)鍵名的數(shù)據(jù)。
刪除數(shù)據(jù),通過key來刪除相應(yīng)的value
localStorage.removeItem("name");
2.3.4 clear():
移除本地存儲(chǔ)所有數(shù)據(jù)。刪除全部存儲(chǔ)的值
localStorage.clear();
示例:
<button id="addData">添加數(shù)據(jù)</button>
<button id="getData">獲取數(shù)據(jù)</button>
<button id="removeData">刪除數(shù)據(jù)</button>
<input type="text" id="txt">
<script>
addData.onclick = function () {
sessionStorage.setItem('name', txt.value);
}
getData.onclick = function () {
alert(sessionStorage.getItem('name'))
}
removeData.onclick = function () {
sessionStorage.removeItem('name')
}
</script>
臨時(shí)存儲(chǔ),只要頁面不關(guān)閉,無論怎么刷新,數(shù)據(jù)都不會(huì)刪除
2.3.5 存儲(chǔ)事件:(了解就OK)
當(dāng)數(shù)據(jù)有修改或刪除的情況下,就會(huì)觸發(fā)storage事件
在對(duì)數(shù)據(jù)進(jìn)行改變的窗口對(duì)象上是不會(huì)觸發(fā)的
- Key : 修改或刪除的key值,如果調(diào)用clear(),key為null
- newValue : 新設(shè)置的值,如果調(diào)用removeStorage(),key為null
- oldValue : 調(diào)用改變前的value值
- storageArea : 當(dāng)前的storage對(duì)象
- url : 觸發(fā)該腳本變化的文檔的url
注:session同窗口才可以,例子:iframe操作
window.addEventListener('storage',function(ev){
console.log(ev.key);
console.log(ev.newValue );
console.log(ev.oldValue );
console.log(ev.storageArea );
console.log(ev.url);
})
2.3.6 兼容問題
那么在老古董瀏覽器上,可以通過使用Cookies來做替代方案并做好域內(nèi)安全。