目录
1.通过localStorage.setItem(key,value)存储数据
1.通过localStorage存储数据,只要不清除,就永久保存
3.通过localStorage.getItem(key)获取存储的数据
4.通过localStorage.removeItem(key)清除某一个通过localStorage存储的数据
5.通过localStorage.clear()清除所有localStorage存储的数据
1.通过sessionStorage.setItem(key,value)存储数据
2.通过sessionStorage.getItem(key)获取存储的数据
1.sessionStorage不仅限制在同源,还限制在同一窗口(只能从本窗口中打开的窗口中才能取到sessionStorage存储的数据)
2.通过sessionStorage存储的数据,只要浏览器窗口一关闭就失效
4.通过sessionStorage.removeItem(key)清除某一个通过sessionStorage存储的数据
5.通过sessionStorage.clear()清除所有sessionStorage存储的数据
2.过期时间 Expires/Max-Age之通过Max-Age设置过期时间
3.过期时间 Expires/Max-Age之通过Expires设置过期时间
2.过期时间如果不设置,那么就是窗口一关闭就失效,如果设置了,那么就是设置了多久失效就多久失效。
-------------------------------------------------------------------------------------
3.一个页面多个ajax同时请求注意:谁先请求后端服务器完成谁就先请求完执行。
1.设置session ctx.session.属性名 = 'value';
客户端存储
前言:很多同源的页面都需要的数据,可以通过 cookie 或者 localStorage 或者 sessionStorage存储。但是数据不要太大,因为客户端存储大小是有限制的
同源策略:浏览器的一种安全防范策略
同源:协议,ip,端口(可以认为域名是ip和端口的组合体)相同,就认为是同源。
eg:百度默认端口号443
客户端存储限制在同源:只要是同源,在本页面利用cookie或者localStorage或者sessionStorage存储数据,在其它页面中也能使用。
1.localStorage
1.通过localStorage.setItem(key,value)存储数据
localStorage.setItem(key,value); 以键值对的形式存储
localStorage.setItem('stuname','蓝色天空');
localStorage.setItem('stuage',22);
2.localStorage存储的特点
1.通过localStorage存储数据,只要不清除,就永久保存
2.存储大小:5M左右
3.通过localStorage.getItem(key)获取存储的数据
console.log(localStorage.getItem('stuage'));
console.log(localStorage.getItem('stuname'));
4.通过localStorage.removeItem(key)清除某一个通过localStorage存储的数据
该方法只清除某一个localStorage存储的数据
5.通过localStorage.clear()清除所有localStorage存储的数据
该方法清除所有通过localStorage存储的数据
2.sessionStorage
1.通过sessionStorage.setItem(key,value)存储数据
<body>
<a href="./客户端存储数据的获取.html">跳到</a>
<h1>存储数据</h1>
<script>
sessionStorage.setItem('flower','红玫瑰');
sessionStorage.setItem('age',22);
</script>
</body>
2.通过sessionStorage.getItem(key)获取存储的数据
console.log(sessionStorage.getItem('flower'));
console.log(sessionStorage.getItem('age'));
3. sessionStorage存储的特点
1.sessionStorage不仅限制在同源,还限制在同一窗口(只能从本窗口中打开的窗口中才能取到sessionStorage存储的数据)
eg:在 存储数据窗口页面,点击超链接跳转到 客户存储数据的获取 窗口页面 满足了是同源,还是从本窗口打开的窗口中,这样才能取到本窗口中通过sessionStorage存储的数据
如果直接打开 客户存储数据的获取 这个窗口页面,就取不到存储数据窗口页面中通过sessionStorage存储的数据。
2.通过sessionStorage存储的数据,只要浏览器窗口一关闭就失效
4.通过sessionStorage.removeItem(key)清除某一个通过sessionStorage存储的数据
该方法只清除某一个sessionStorage存储的数据
5.通过sessionStorage.clear()清除所有sessionStorage存储的数据
该方法清除所有通过sessionStorage存储的数据
3.cookie
1.通过 document.cookie = ' '; 存储数据
document.cookie = 'beauty = 宋花花';
document.cookie = 'age = 22';
2.通过 document.cookie 获取数据
//存储
document.cookie = `stuage=21`;
document.cookie = `stuname1=red`;
//获取
console.log(document.cookie);
3.清除cookie所存的数据
一般不用给cookie清除数据,因为它的过期时间一到就会自动清除,如果要让它马上清除,可以给其过期时间设置为0
document.cookie = `stuname1=red;max-age=${0};path=/`;
或者在浏览器中直接把其 x 掉。
4.cookie有很多属性 路径path 过期时间Expires/Max-Age 域名Domain
1. 路径 path
路径 如果不指定,默认就是 指向写cookie存储数据那个html文件所在的文件夹,也就是只有那个文件夹下的文件才能访问到 cookie所存的数据,不是那个文件夹下的文件就不能访问到。
所以一般把 path属性值设置为整个项目的根目录,这样整个根目录下的文件就都能访问到cookie中所存储的值。
document.cookie = `stuname1 = 100;path=/`;
分析:path=/ 就表示把 路径设置为整个项目的根目录。该项目下的其它文件也就可以访问到 cookie中存的数据。
2.过期时间 Expires/Max-Age之通过Max-Age设置过期时间
如果不指定过期时间:默认是Session,也就是窗口一关闭就消失(该文件所在目录下的其它文件就不能访问到cookie中存的值了)
指定过期时间:注意点:这个单位是秒,不是毫秒
eg:7天后过期(max-age一般写在path前面)
document.cookie = `stuname1 = 100;max-age=${7*24*60*60};path=/`;
分析:设置成功。
问题:
问题:如果 Domain , Path, Max-Age都一样了,设置两次stuname1会不会cookie存两个Name为 stuname1的数据?
//域名,path,max-age 都相同
document.cookie = `stuname1=blue`;
document.cookie = `stuname1=red`;
结果:
分析:相当于是给同一属性设置的,后者会覆盖前者。
3.过期时间 Expires/Max-Age之通过Expires设置过期时间
注意点:通过Expires设置过期时间的话,其单位不是秒,是一种Expires可以识别的格式,需要自己手动设置。
<script>
//存储
let tim = new Date(); //得到是现在的时间
tim.getTime(); //拿到当前的时间戳 毫秒值
// tim.getTime()+7*24*60*60*1000 //未来7天 这是未来7天的时间戳
tim.setTime(tim.getTime()+7*24*60*60*1000);//传一个时间戳,就可以把传入的时间戳转成对应的时间
console.log(tim); //这个时候打印 tim 就不是当前的时间了而是未来7天的时间
//然后转换为 Expires 可以识别的时间格式 调用toGMTString方法
document.cookie = `stuname1=red;expires=${tim.toGMTString()};path=/`;
</script>
5.cookie存储的特点
1.存储大小:4K左右
2.过期时间如果不设置,那么就是窗口一关闭就失效,如果设置了,那么就是设置了多久失效就多久失效。
4.cookie的封装
1.cookie存储的封装
<script>
function setCookie(key, value, day) {
document.cookie = `${key}=${value};max-age=${day*24*60*60};path=/`;
//针对于 Expires
// let tim = new Date();
// tim.getTime();
// tim.setTime(tim.getTime() + day * 24 * 60 * 60 * 1000);
// document.cookie = `${key}=${value};expires=${tim.toGMTString()};path=/`;
}
//setCookie(key,value,day); //这里day表示天数
setCookie('stuage', '21', 7);
setCookie('stuname','宋花花',7);
setCookie('num',200,7);
</script>
取存储的数据,结果为:
console.log(document.cookie); //'num=200; stuage=21; stuname=宋花花'
分析:会把cookie存的所有数据放到一个字符串里面打印出来。
2.获取cookie存储数据的封装
分析:通过document.cookie获取的是所有通过cookie保存的数据,但是如果只是想获取某一个通过cookie保存的数据就不行,这里封装的函数就可实现。
<script>
function getCookie(key){
let allCookie = document.cookie; //'num=200; stuage=21; stuname=宋花花'
let allCookieArr = allCookie.split('; '); //['num=200', 'stuage=21', 'stuname=宋花花']
for(let i=0;i<allCookieArr.length;i++){
if(allCookieArr[i].includes(key)){
return allCookieArr[i].split('=')[1]; //['stuname','宋花花']
}
}
return null;
}
console.log(getCookie('stuname')); //宋花花
</script>
5.cookie的简单应用
通过cookie设置过期时间,可以设置判断用户的登录状态,如果过期了,就需要重新登录。
登录:login 页面
<body>
<form>
<!-- 手机号11位数 -->
账号: <input type="text" name="account">
<br>
<!-- 6-12位 -->
密码: <input type="password" name="pwd">
<br>
<input type="button" value="登录" id="loginBtn">
</form>
<script>
let loginBtn = document.querySelector('#loginBtn');
let account = document.querySelector('input[name="account"]');
let pwd = document.querySelector('input[name="pwd"]');
loginBtn.onclick = function () {
//判断账号和密码是否满足格式--正则(前端)
let reg = /^1[3-9]\d{9}$/ig;
if (!reg.test(account.value)) {
alert('账号输入的手机格式不对,请重新输入');
return;
}
if (pwd.value.length < 6 || pwd.value.length > 12) {
alert('密码格式不对,请输入6-12位的密码');
return;
}
//把账号和密码存入到cookie里面,设置过期时间,可以判断用户的登录状态,如果过期了就需要重新登录
function setCookie(key, value, day) {
document.cookie = `${key}=${value};max-age=${day*24*60*60};path=/`;
}
//setCookie(key,value,day); //这里day表示天数
setCookie('account',account.value, 7);
setCookie('pwd',pwd.value, 7);
window.location.href = './stuname.html';
}
</script>
</body>
学生详情页:
<body>
<h1>学生详情页</h1>
<script>
function getCookie(key){
let allCookie = document.cookie;
let allCookieArr = allCookie.split('; ');
for(let i=0;i<allCookieArr.length;i++){
if(allCookieArr[i].includes(key)){
return allCookieArr[i].split('=')[1];
}
}
return null;
}
//判断用户是否处于登录状态,就是看cookie保存的账号和密码过期没有,过期了就要回到登录页面重新登录
if(!getCookie('account')){
window.location.href = './login.html';
}else{
console.log(getCookie('account'));
}
</script>
</body>
-------------------------------------------------------------------------------------
服务器存储 cookie + session
基于egg来讲解的cookie和session:
1.后端服务器存储cookie
1.设置cookie:ctx.cookies.set(key, value);
ctx.cookies.set('num1',100);
ctx.cookies.set('num2',200);
前端利用axios框架进行ajax请求后端设置的cookie,可以在浏览器控制台对应的响应头(设置后端cookie那个接口)中找到后端服务器设置的cookie
2.获取cookie ctx.cookie.get(key);
3.一个页面多个ajax同时请求注意:谁先请求后端服务器完成谁就先请求完执行。
ajax请求是异步的,一个页面可能会同时发起多个ajax请求,但是,ajax请求并不是哪个写在前面,哪个就先请求完执行。而是当一个页面同时发起ajax请求时,发起的多个ajax请求都是同时进行的,谁先请求后端服务器完成谁就先请求完执行。
当一个页面同时发起多个ajax请求的时候,哪一次ajax请求先完成是不确定的,因为每个ajax请求的路由所要进行的功能是不同的,所消耗的时间是不同的。
问题:如果要想在请求后端 cookie设置完成后再去获取后端设置的cookie,怎么办?
这样:
<script>
axios.get(`http://127.0.0.1:7001/setcookie`)
.then(function (response) {
//请求后端接口成功就会执行,请求成功后的数据放在response里面
console.log('cookie设置成功:', response);
})
.catch(function (error) {
console.log(error);
})
axios.get(`http://127.0.0.1:7001/getcookie`)
.then(function (response) {
console.log('cookie获取成功:', response);
})
.catch(function (error) {
console.log(error);
})
</script>
分析:这是同时发起2个ajax请求,不能保证到底谁先执行完,所以上面这种不可以。
<script>
axios.get(`http://127.0.0.1:7001/setcookie`)
.then(function (response) {
console.log('cookie设置成功:', response);
//请求完成,并成功 cookie设置完成 才进行取 cookie
axios.get(`http://127.0.0.1:7001/getcookie`)
.then(function (response) {
console.log('cookie获取成功:', response);
})
.catch(function (error) {
console.log(error);
})
})
.catch(function (error) {
console.log(error);
})
</script>
分析:这样才能保证先设置好了后端cookie,才能获取到。
4.服务器cookie总结:(很重要)
cookie:设置cookie:ctx.cookies.set(key,value)
获取cookie: ctx.cookie.get(key)
1.后端的cookie的存储位置:后端设置的cookie会存储在客户端浏览器里面,前端设置的也在客户端浏览器里面,且所在的位置相同。
2.客户端浏览器里面的cookie(前端和后端设置的cookie都在客户端浏览器里面)会出现在请求头里面,原因是每次发起请求的时候都会携带客户端里面存储的cookie发给服务器(不管是前端设置的cookie还是后端设置的cookie) --> 前端每次发起请求(只要请求有请求头,里面就会携带cookie发送给服务器)
分析:同源才会在请求头里面出现cookie,不同源不会在请求头中出现cookie。 然后不同源也想在请请求头中出现cookie,就要就行cookie跨域配置。
3.后端设置cookie,限制在同源才能正常存储并获取传输(请求头里面有cookie),如果想要在跨域的情况下也要正常存储并获取,那么就需要设置允许跨域存储cookie -->跨域设置
01.在同源情况下,才能将存储在浏览器里面的后端cookie通过发送ajax请求,通过后端代码ctx.cookie.get(key) 获取到。
前端代码:
<script>
axios.get(`http://127.0.0.1:7001/setcookie`)
.then(function (response) {
console.log('cookie设置成功:', response);
//请求完成,并成功 cookie设置完成 才进行取 cookie
axios.get(`http://127.0.0.1:7001/getcookie`)
.then(function (response) {
console.log('cookie获取成功:', response);
})
.catch(function (error) {
console.log(error);
})
})
.catch(function (error) {
console.log(error);
})
</script>
后端代码:
前端结果:
02.在不同源情况下,不能将存储在浏览器里面的后端cookie通过发送ajax请求,然后通过后端代码ctx.cookie.get(key) 获取到。
03.如果不是同源,也想将存储在浏览器里面的后端cookie通过发送ajax请求,然后通过后端代码ctx.cookie.get(key) 获取到,就要进行跨域配置:
后端egg需要设置的:
//配置cors:在 config/config.default.js
// 跨域的配置
config.cors = {
// origin: '*', //允许的域,*代表所有的
//origin: 'http:127.0.0.1:80', //如果想携带cookie,这里必须指定ip和端口号
origin: 'http:127.0.0.1',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', //允许跨域的请求方法
credentials:true //后端允许跨域携带cookie
};
分析: origin: 'http:127.0.0.1:80' 如果这里写了端口号80,浏览器地址栏也要写端口号80,即使可以省略不写,也得添上80,不然就是跨域。但是不写80最好,因为80是apache的默认端口,浏览器会自动省略80,而这里又写了80,但是跨域要求很严格,必须要和配置的一样,即使可以省略也不行,所以最好不写80(因为写了,浏览器又中也写80,但是会自动省略掉,跟这里就不一样了,就会报跨域)
前端也要设置:如果是get请求:
//表示跨域请求时是否需要使用凭证(cookie)
//withCredentials: true 表示需要
axios.get(url,{params:dataObj, withCredentials: true })
分析:默认不需要,为fasle,如果需要跨域传输cookie,则为true,请求设置和获取后端cookie都要设置:
axios.get(`http://127.0.0.1:7001/setcookie`, {
withCredentials: true
})
.then(function (response) {
console.log('cookie设置成功:', response);
//请求完成,并成功 cookie设置完成 才进行取 cookie
axios.get(`http://127.0.0.1:7001/getcookie`, {
withCredentials: true
})
.then(function (response) {
console.log('cookie获取成功:', response);
})
.catch(function (error) {
console.log(error);
})
})
.catch(function (error) {
console.log(error);
})
前端也要设置:如果是post请求:
axios.post(url,dataObj,{withCredentials: true })
axios.post('http://127.0.0.1:8000/login', {
//给后端传递的数据
account: account,
pwd: pwd
},{withCredentials: true })
.then(function (response) {
//请求后端成功后,后端返回给前端的数据:response
console.log(response);
alert(response.data.data);
if (response.data.data == '登录成功') {
//账号和密码正确就跳转到student.html
window.location.href = './students.html';
}
})
.catch(function(error){
//请求后端失败了,失败原因在error
console.log('请求后端失败了,失败原因为:',error);
})
结果:
4.客户端浏览器里面保存前后端的cookie,虽然会每次发起请求都会携带在请求头里面,然后发送给服务器,但是后端服务器是拿不到的(ctx.cookies.get(前端cookie的key)),只能获取后端cookie。后端设置的cookie,虽然是保存在客户端浏览器里面,但是前端去获取(document.cookie),是获取不到的,只能获取到前端cookie
2.后端服务器存储 session
1.设置session ctx.session.属性名 = 'value';
async setsession() {
const {ctx} = this;
ctx.session.id = 101;
ctx.session.account = '18996883123';
ctx.body = 'session设置成功';
}
2.获取session ctx.session.属性名
async getsession() {
const {ctx} = this;
let id = ctx.session.id;
let account = ctx.session.account;
ctx.body = {
id,account
};
}
3.与cookie一样,session在不跨域的情况下才能正常设置和获取,在跨域的情况下就获取不到。
同源情况下:前后端代码都在egg里面
不同源的情况下:前端代码在apache中,后端代码在egg中
4.同源情况下:后端在用session存储数据的时候,会创建一个cookie(EGG_SESS),这个cookie会自动保存在客户端浏览器里面。
5.不同源情况下:后端在用session存储数据的时候,还是会创建一个cookie(EGG_SESS),但是这个cookie不会保存在客户端浏览器里面)。
6.不跨域情况下:后端用session存储数据的时候,会创建一个唯一的cookie(EGG_SESS),然后当后端(不是设置session那个接口,其它后端接口)要获取存储的session数据时,必须根据在用session存储数据的时候创建的这个cookie值解析对应的session
分析:后端通过session保存数据时,会自动生成一个cookie(EGG_SESS)然后保存到前端浏览器里面,然后当需要取出session里面的数据时,前端就把生成的cookie(EGG_SESS)放在请求头里面传给后端,后端根据这个cookie值解析出session中保存的数据。
7.如果要跨域的情况下实现6的效果,就要配置跨域。类似cookie跨域配置一样。
后端egg需要设置的:
//配置cors:在 config/config.default.js
// 跨域的配置
config.cors = {
// origin: '*', //允许的域,*代表所有的
//origin: 'http:127.0.0.1:80', //如果想携带cookie,这里必须指定ip和端口号
origin: 'http:127.0.0.1',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', //允许跨域的请求方法
credentials:true //后端允许跨域携带cookie
};
前端也要设置:如果是get请求:
//表示跨域请求时是否需要使用凭证(cookie)
//withCredentials: true 表示需要
axios.get(url,{params:dataObj, withCredentials: true })
<script>
axios.get(`http://127.0.0.1:7001/setsession`, {
withCredentials: true
})
.then(function (response) {
console.log('setsession设置成功:', response);
//请求完成,并成功 cookie设置完成 才进行取 cookie
axios.get(`http://127.0.0.1:7001/getsession`, {
withCredentials: true
})
.then(function (response) {
console.log('getsession获取成功:', response);
})
.catch(function (error) {
console.log(error);
})
})
.catch(function (error) {
console.log(error);
})
</script>
前端也要设置:如果是post请求:
axios.post(url,dataObj,{withCredentials: true })
结果:
8.存一些重要的数据,就用session,因为cookie会在浏览器中暴露,而session是通过后端解码得到数据。不会将数据暴露在浏览器中。
9.一个客户端浏览器中只有一个通过session存储产生的cookie
eg:你后端在写登录接口时,需要用到session存储数据,相应得前端就会生成一个cookie值(cookie(EGG_SESS)),然后你后端写注册接口时,需要用到session存储数据,此时前端就不会生成一个新得cookie值(cookie(EGG_SESS)),一个客户端浏览器只有一个通过session创建得cookie(cookie(EGG_SESS)),只是(cookie(EGG_SESS))里面数据会因为session存储不同,会更新而已,但是整个客户端浏览器只有一个通过session创建得cookie(cookie(EGG_SESS))
10.session得默认配置(包含过期时间)+删除session
在Egg框架config.default.js文件里面
exports.session = {
key: 'EGG_SESS',
maxAge: 24 * 3600 * 1000, // 默认是1 天
httpOnly: true,
encrypt: true,
};
也可以在代码里面设置session的过期时间(但是不建议)
//设置session得过期时间(1分钟后过期)
ctx.session.maxAge = 60*1000;
如果想删除session,直接将它赋值为null
ctx.session = null;