1.cookie
是由W3C组织提出,最早由Netscape社区发展的一种机制。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
简单说cookie会话跟踪技术
1.1. cookie的作用与特性
cookie是存储在浏览器中的缓存信息
1.1.1 作用:
- 登录记录
- 多个页面的数据传递
- 保存用户信息
1.1.2 完整的格式
name=value;[expires=date];[path=path]
1.1.3 特点:
- 存值不大(最大可以存4kb)
- 每个域名下最多存储50条数据(不同浏览器会有不同)
- 可以自己设置过期时间
- 具有不可跨域性
1.1.4 中文的编码
中文与英文字符不同,中文属于Unicode字符,在内存中占2个字符(4个字节),而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。
所以cookie直接存中文可能会出现乱码
encodeURIComponent 将中文编译成对应的字符
decodeURIComponent 将对应的字符转为中文
这两个方法互逆,都是window上带的方法,可以直接用
<script>
let str = '心存美好'
let aa =encodeURIComponent(str);
console.log(aa);
let bb = decodeURIComponent(aa)
console.log(bb)
</script>
1.2. 设置cookie
我们可以先检查缓存cookie
console.log(document.cookie)//实际上设置cookie之前是没有cookie值的
设置cookie
document.cookie = 'name=wuwei'
<script>
//检查/获取本地cookie
console.log(document.cookie)
//设置本地cookie
document.cookie = 'name=心存美好' //表示一条cookie记录 有属性和值
document.cookie = 'age=18';
document.cookie = 'hooby=sing'
//控制台-->Application-->Storage(左侧)-->Cookies-->127.0.0.1:5500服务中可以看到记录
</script>
默认cookie的结束时间是关闭浏览器的时候
1.3.. 设置过期时间
设置cookie的过期时间使用expires
<script> // console.log(new Date)//时间对象格式 // console.log(new Date().toGMTString())//字符串时间格式 let date = new Date(new Date().getTime() + 3000);//用getTime先转成毫秒数,加上3000ms,再转成时间 document.cookie = `name=美好;expires=${date.toGMTString()}` //cookie时间过期会自动删除cookie,过期就访问不到 console.log(date) </script>
<script>
//max-age设置cookie时间
document.cookie = `name=美好;max-age=`//单位是s,超过时间自动删除也可以写成`name=美好;max-age=3`
</script>
过期时间不能小于当前时间,因为小于当前时间,说明cookie已经过期了
var date = new Date(new Date().getTime() -1) ;
所谓的删除cookie 就是让cookie 已经到达过期时间, cookie一旦过期, 会自动删除
<script>
document.cookie = 'name=美好'
del.onclick = function () {
let date = new Date(new Date().getTime() - 10);//设置成-10就会立即过期//删除方法一
document.cookie = `name=美好;expires=${date.toGMTString()}`
// document.cookie = `name=美好;max-age = 1.4. 设置多个cookie
`//删除方法二
}
</script>
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. 封装设置cookie
1.5.1 设置cookie
// 封装的设置一个cookie的函数
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
})
// 设置单个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设置
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) {//如果存在这个属性就加上
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,//过期时间
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{
// 查询结束的位置
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
function removeCookie(name){
document.cookie = encodeURIComponet(name) + "=;expires=" + new Date(0)
}
清除cookie
思路就是将cookie时间设置为已经过期的时间浏览器会自动清楚过期的cookie
1.6. 封装设置多个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. 设置所有cookie常用的属性
描述 | name |
---|---|
该Cookie的名称。Cookie一旦创建,名称便不可更改 | value |
该Cookie的值。如果值为Unicode字符,需要为字符编码。 | expires |
设置cookie的过期时间使用expires(确定的时间) | maxAge |
max-age用秒来设置cookie的生存期 | path |
该Cookie的使用路径 | domain |
可以访问该Cookie的域名。(localhost) | secure |
该Cookie是否仅被使用安全协议传输。安全协议。默认为false<br />如果不设置字段 cookie 可以通过http,https 协议加载设置<br />如果设置这个字段, 那么只能通过https协议才能设置成 | HTTP-Only |
HTTP-Only 背后的意思是告之浏览器该 cookie 绝不能通过 JavaScript 的 2.本地存储属性访问。<br />默认是false(没有值),前端就可以访问。如果值为true,则只有后端可以访问前端不可以访问。<br />控制台中双击就可以true、false切换 |
2.1. Storage
本地存储是HTML5中新增的特性,用来解决cookie存储空间不足的问题
1、概述:
对于Web Storage来说,实际上是Cookies存储的进化版。
背熟这句口诀:“两个接口,四个函数”。
2、口诀:
(1)两个接口:分别是sessonStorage(临时存储)和localStorage(本地存储)
(2)四个函数:分别是setItem、getItem、removeItem和clear。(设置、获取、删除、)
2.1.1 sessionStorage
session临时回话,从页面打开到页面关闭的时间段
窗口的临时存储,页面关闭,本地存储消失
临时存储就是存储一下,其他页面并不会共享
<body>
<!-- 本地存储 -->
<input type="text" name="" id="text">
<button id="addData">设置</button>
<button id="addData2">设置2</button>
<button id="addData3">设置3</button>
<button id="getData">获取</button>
<button id="removeData">删除</button>
<button id="clearData">清空</button>
<div id="box"></div>
<div id="box3"></div>
<!--获取的数据内容添加到这里 -->
<script>
//查看临时会话 控制台--》Application-->storage-->sesssion Storage--->127.0.0.1:5500。页面关闭时数据就消失
addData.onclick = function () {//设置
console.log(11);
if (text.value.trim()) {//点击设置,判断是否有值
sessionStorage.setItem('name', text.value)//有值设置input的值,设置后在Application-->storage-->sesssion Storage--->127.0.0.1:5500就会看到,要删除默认的值
} else {
alert('请输入内容')//点击设置,为空出现弹框
}
}
addData2.onclick = function () {//设置的另一个age值,字段名和字段值一一对应
console.log(11);
if (text.value.trim()) {
sessionStorage.setItem('age', text.value)
} else {
alert('请输入内容')
}
}
addData3.onclick = function () {//设置的另一个age值,字段名和字段值一一对应
console.log(11);
if (text.value.trim()) {
sessionStorage.setItem('user', JSON.stringify({
name: '张五', age: '50'
}))//即使存储的是对象,控制台里也会自动转成字符串[object,Object]。要使用JSON.stringify转成字符串才是对象字符串
} else {
alert('请输入内容')
}
}
getData.onclick = function () {
console.log(22)
let data = sessionStorage.getItem('name')//传获取的字段名,要获取name字段名
box.innerHTML = data;//点击‘获取’就将input里的值取出来了,放到页面上了
let data3 = sessionStorage.getItem('user')
console.log(typeof data3)
console.log(data3)//这时是字符串
console.log(JSON.parse(data3))//通过JSON.parse转成了对象,点开控制台原型可以看到
box3.innerHTML = data3;
}
removeData.onclick = function () {
console.log(33)
sessionStorage.removeItem('name')
}
clearData.onclick = function () {
console.log(44);
sessionStorage.clear()//全部干掉了
}
// 特性
// 1.sessionStorage是临时会话,如果页面关闭数据自动删除
// 2.数据不共享,即使同一个网站同一个页面数据也不共享。
// 3.存储的数据都是字符串,如果想要存对象或数组,先使用JSON转成字符串
</script>
</body>
// JSON.stringify() 把对象类型转成字符串
// JSON.parse() 把字符串解析成对象
let obj = { //这个数据传给后端时,后端不一定识别,但字符串是所有浏览器都能识别的,通过JSON.stringify()转成字符串
name: '张三',
age: 19
}
let aa = JSON.stringify(obj) //对象转字符串
let bb = JSON.parse(aa)//字符串解析成对象
console.log(typeof aa)
console.log(typeof bb)
// JSON对象:对象格式的JSON
// JSON数组:数组格式的JSON
let arr = [10, 20, 30, { name: '张三' }]
let arrJSON = JSON.stringify(arr)
console.log(arrJSON)
console.log(typeof arrJSON)//数组格式的JSON
console.log(JSON.parse(arrJSON))//此时又将json转成数组了
// JSON在js中外部需要加单引号'',JSON单独创建xxx.json文件时就不需要单引号了,直接在文件里写内容就可以{"":"","":""},json文件里也都需要双引号
JSON是js内置的一个对象。JSON是有固定格式的字符串。JSON里面的字段必须要双引。
2.1.2 localStorage
域内安全、永久保存。浏览器不删除,会一直存储着数据。即客户端或浏览器中来自同一域名的所有页面都可访问localStorage数据且数据除了删除否则永久保存,但客户端或浏览器之间的数据相互独立。
永久存储(可以手动删除数据)
多个页面可以共享
<body>
<!-- 本地存储 -->
<input type="text" name="" id="text">
<button id="addData">设置</button>
<button id="addData2">设置2</button>
<button id="addData3">设置3</button>
<button id="getData">获取</button>
<button id="removeData">删除</button>
<button id="clearData">清空</button>
<div id="box"></div>
<div id="box3"></div>
<script>
//此时打开控制台 --》Application-->localStorage中没有数据。
//输入数据后--》点设置,控制台中就有数据了。
//此时再开启新页面,控制台中刚刚设置的数据依然存在
addData.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('name', text.value)
} else {
alert('请输入内容')
}
}
addData2.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('age', text.value)
} else {
alert('请输入内容')
}
}
addData3.onclick = function () {
console.log(11);
if (text.value.trim()) {
localStorage.setItem('user', JSON.stringify({
name: '张五', age: '50'
}))
} else {
alert('请输入内容')
}
}
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的特点
- 存储量限制 ( 5M ) 客户端微型数据库
- 客户端完成,不会请求服务器处理
- sessionStorage数据是不共享、 localStorage共享
- 浏览器不统一,并且在IE8以下不兼容
- 储存的值限定是字符串类型,需要我们通过JSON 对象去转换
- 存储内容多的话会消化内容空间,会导致变卡
2.3. Storage API
2.3.1 setItem(键名,键值):
设置数据,(key,value)类型,类型都是字符串
可以用获取属性的形式操作
在本地客户端存储一个字符串类型的数据,其中,第一个参数“键名”代表了该数据的标识符,而第二个参数“键值”为该数据本身。
localStorage.setItem("name", "wuwei");
例如:
2.3.2 getItem():
读取已存储在本地的数据,通过键名作为参数读取出对应键名的数据。如:
获取数据,通过key来获取到相应的value
var data = localStorage.getItem("name");
2.3.3 removeItem():
移除已存储在本地的数据,通过键名作为参数删除对应键名的数据。
删除数据,通过key来删除相应的value
localStorage.removeItem("name");
2.3.4 clear():
移除本地存储所有数据。删除全部存储的值
localStorage.clear();
示例:
<button id="addData">添加数据</button>
<button id="getData">获取数据</button>
<button id="removeData">删除数据</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>
2.3.5 存储事件:(了解就OK)
临时存储,只要页面不关闭,无论怎么刷新,数据都不会删除
当数据有修改或删除的情况下,就会触发storage事件
在对数据进行改变的窗口对象上是不会触发的
- newValue : 新设置的值,如果调用removeStorage(),key为null
- oldValue : 调用改变前的value值
- storageArea : 当前的storage对象
- url : 触发该脚本变化的文档的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来做替代方案并做好域内安全。