目录
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存储的数据
1.通过 document.cookie = ' '; 存储数据
4.cookie有很多属性 路径path 过期时间Expires/Max-Age 域名Domain
2.过期时间 Expires/Max-Age之通过Max-Age设置过期时间
3.过期时间 Expires/Max-Age之通过Expires设置过期时间
2.过期时间如果不设置,那么就是窗口一关闭就失效,如果设置了,那么就是设置了多久失效就多久失效。
-------------------------------------------------------------------------------------
1.设置cookie:ctx.cookies.set(key, value);
2.获取cookie ctx.cookie.get(key);
3.一个页面多个ajax同时请求注意:谁先请求后端服务器完成谁就先请求完执行。
1.后端的cookie的存储位置:后端设置的cookie会存储在客户端浏览器里面,前端设置的也在客户端浏览器里面,且所在的位置相同。
3.后端设置cookie,限制在同源才能正常存储并获取传输(请求头里面有cookie),如果想要在跨域的情况下也要正常存储并获取,那么就需要设置允许跨域存储cookie -->跨域设置
1.设置session ctx.session.属性名 = 'value';
3.与cookie一样,session在不跨域的情况下才能正常设置和获取,在跨域的情况下就获取不到。
4.同源情况下:后端在用session存储数据的时候,会创建一个cookie(EGG_SESS),这个cookie会自动保存在客户端浏览器里面。
5.不同源情况下:后端在用session存储数据的时候,还是会创建一个cookie(EGG_SESS),但是这个cookie不会保存在客户端浏览器里面)。
7.如果要跨域的情况下实现6的效果,就要配置跨域。类似cookie跨域配置一样。
8.存一些重要的数据,就用session,因为cookie会在浏览器中暴露,而session是通过后端解码得到数据。不会将数据暴露在浏览器中。
前言:很多同源的页面都需要的数据,可以通过 cookie 或者 localStorage 或者 sessionStorage存储。但是数据不要太大,因为客户端存储大小是有限制的
同源策略:浏览器的一种安全防范策略
同源:协议,ip,端口(可以认为域名是ip和端口的组合体)相同,就认为是同源。
eg:百度默认端口号443
客户端存储限制在同源:只要是同源,在本页面利用cookie或者localStorage或者sessionStorage存储数据,在其它页面中也能使用。
localStorage.setItem(key,value); 以键值对的形式存储
- localStorage.setItem('stuname','蓝色天空');
- localStorage.setItem('stuage',22);
- console.log(localStorage.getItem('stuage'));
- console.log(localStorage.getItem('stuname'));
该方法只清除某一个localStorage存储的数据
该方法清除所有通过localStorage存储的数据
-
- <a href="./客户端存储数据的获取.html">跳到a>
- <h1>存储数据h1>
- <script>
- sessionStorage.setItem('flower','红玫瑰');
- sessionStorage.setItem('age',22);
- script>
-
- console.log(sessionStorage.getItem('flower'));
- console.log(sessionStorage.getItem('age'));
eg:在 存储数据窗口页面,点击超链接跳转到 客户存储数据的获取 窗口页面 满足了是同源,还是从本窗口打开的窗口中,这样才能取到本窗口中通过sessionStorage存储的数据
如果直接打开 客户存储数据的获取 这个窗口页面,就取不到存储数据窗口页面中通过sessionStorage存储的数据。
该方法只清除某一个sessionStorage存储的数据
该方法清除所有通过sessionStorage存储的数据
- document.cookie = 'beauty = 宋花花';
- document.cookie = 'age = 22';
- //存储
- document.cookie = `stuage=21`;
- document.cookie = `stuname1=red`;
- //获取
- console.log(document.cookie);
一般不用给cookie清除数据,因为它的过期时间一到就会自动清除,如果要让它马上清除,可以给其过期时间设置为0
document.cookie = `stuname1=red;max-age=${0};path=/`;
或者在浏览器中直接把其 x 掉。
路径 如果不指定,默认就是 指向写cookie存储数据那个html文件所在的文件夹,也就是只有那个文件夹下的文件才能访问到 cookie所存的数据,不是那个文件夹下的文件就不能访问到。
所以一般把 path属性值设置为整个项目的根目录,这样整个根目录下的文件就都能访问到cookie中所存储的值。
document.cookie = `stuname1 = 100;path=/`;
分析:path=/ 就表示把 路径设置为整个项目的根目录。该项目下的其它文件也就可以访问到 cookie中存的数据。
如果不指定过期时间:默认是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`;
结果:
分析:相当于是给同一属性设置的,后者会覆盖前者。
注意点:通过Expires设置过期时间的话,其单位不是秒,是一种Expires可以识别的格式,需要自己手动设置。
-
- //存储
- 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=/`;
-
-
- 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);
-
取存储的数据,结果为:
console.log(document.cookie); //'num=200; stuage=21; stuname=宋花花'
分析:会把cookie存的所有数据放到一个字符串里面打印出来。
分析:通过document.cookie获取的是所有通过cookie保存的数据,但是如果只是想获取某一个通过cookie保存的数据就不行,这里封装的函数就可实现。
-
- 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
length;i++){ - if(allCookieArr[i].includes(key)){
- return allCookieArr[i].split('=')[1]; //['stuname','宋花花']
- }
- }
- return null;
- }
- console.log(getCookie('stuname')); //宋花花
-
通过cookie设置过期时间,可以设置判断用户的登录状态,如果过期了,就需要重新登录。
登录:login 页面
-
-
- 账号:
-
-
- 密码:
-
-
-
-
- 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';
- }
-
学生详情页:
- <h1>学生详情页h1>
- <script>
- function getCookie(key){
- let allCookie = document.cookie;
- let allCookieArr = allCookie.split('; ');
- for(let i=0;i
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>
基于egg来讲解的cookie和session:
- ctx.cookies.set('num1',100);
- ctx.cookies.set('num2',200);
前端利用axios框架进行ajax请求后端设置的cookie,可以在浏览器控制台对应的响应头(设置后端cookie那个接口)中找到后端服务器设置的cookie
ajax请求是异步的,一个页面可能会同时发起多个ajax请求,但是,ajax请求并不是哪个写在前面,哪个就先请求完执行。而是当一个页面同时发起ajax请求时,发起的多个ajax请求都是同时进行的,谁先请求后端服务器完成谁就先请求完执行。
当一个页面同时发起多个ajax请求的时候,哪一次ajax请求先完成是不确定的,因为每个ajax请求的路由所要进行的功能是不同的,所消耗的时间是不同的。
问题:如果要想在请求后端 cookie设置完成后再去获取后端设置的cookie,怎么办?
这样:
-
- 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);
- })
-
分析:这是同时发起2个ajax请求,不能保证到底谁先执行完,所以上面这种不可以。
-
- 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);
- })
-
分析:这样才能保证先设置好了后端cookie,才能获取到。
cookie:设置cookie:ctx.cookies.set(key,value)
获取cookie: ctx.cookie.get(key)
分析:同源才会在请求头里面出现cookie,不同源不会在请求头中出现cookie。 然后不同源也想在请请求头中出现cookie,就要就行cookie跨域配置。
01.在同源情况下,才能将存储在浏览器里面的后端cookie通过发送ajax请求,通过后端代码ctx.cookie.get(key) 获取到。
前端代码:
-
- 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);
- })
-
后端代码:
前端结果:
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);
- })
结果:
- async setsession() {
- const {ctx} = this;
- ctx.session.id = 101;
- ctx.session.account = '18996883123';
- ctx.body = 'session设置成功';
- }
- async getsession() {
- const {ctx} = this;
- let id = ctx.session.id;
- let account = ctx.session.account;
- ctx.body = {
- id,account
- };
- }
同源情况下:前后端代码都在egg里面
不同源的情况下:前端代码在apache中,后端代码在egg中
分析:后端通过session保存数据时,会自动生成一个cookie(EGG_SESS)然后保存到前端浏览器里面,然后当需要取出session里面的数据时,前端就把生成的cookie(EGG_SESS)放在请求头里面传给后端,后端根据这个cookie值解析出session中保存的数据。
后端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 })
-
- 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);
- })
-
前端也要设置:如果是post请求:
axios.post(url,dataObj,{withCredentials: true })
结果:
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))
在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;