cookie(失效,跨域,节流),session,操作localStorage增删查,vuex配合localStorage增删改

22 篇文章 0 订阅
6 篇文章 0 订阅

前言:
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份.

一 什么是cookie

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

1.1 cookie的原理

一个cookie的设置以及发送过程分为以下四步:

  1. 客户端发送一个http请求到服务器端
  2. 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
  3. 客户端发送一个http请求到服务器端,其中包含Cookie头部
  4. 服务器端发送一个http响应到客户端
    在这里插入图片描述

1.2 操作cookie

cookie的常用属性:

// 1. expires 有效期
// 2. path 路径
// 3. domain 域名

1.2.1 服务器操作cookie

php操作cookie

// 设置cookie
// setcookie(name, value, expire, path, domain);
// 设置1小时后过期
setcookie("user", "lisi", time()+3600);
// 获取单个cookie
echo $_COOKIE["user"];
// 查看所有cookie
print_r($_COOKIE);

1.2.2 (客服端)JS操作cookie

// 设置cookie
function setCookie(key,value,param){
    document.cookie = key + '=' + value + '; expires=' + param.expires + '; path=' + param.path; 
}
// 获取cookie
function getCookie(key){
    var cookies = document.cookie;
    var arr = cookies.split('; ');
    if(arr){
        for (var i = 0; i < arr.length; i++) {
            var kv = arr[i].split('=');
            if(kv[0] == key){
                return kv[1];
            }
        }
    }
}

1.2.3 jQuery操作cookie

cookie插件基本使用
设置单个cookie
获取单个cookie
获取所有cookie
删除单个cookie
浏览器中cookie基本设置

1.3 cookie的节流

因为浏览器每次发送http请求的时候,都会带上cookie,这样如果浏览器请求的静态资源(图片等)也会带上cookie,那样会造成比较严重的带宽浪费.

解决办法:

1. 利用cdn实现请求静态资源是一个服务器,实现业务逻辑是一个服务器.
2. 严格控制cookie存放的有效,有用信息

1.4 cookie的跨域

二 什么是session

seesion是为了解决cookie安全问题的,把数据存入前端太危险,(数据存入服务端)

因为如果重要的数据都存在浏览器端,这样的数据容易泄露以及被修改,所以我们把原来存在cookie中部分数据存到服务器端.这种技术就叫session.

session可以理解为是服务器上的一个保险柜,把所有数据都保存在服务器的保险柜里,只给浏览器一把钥匙用来访问这些数据。数据都是存在服务器端,而浏览器端只存一把 钥匙。因为要把 钥匙给浏览器存起来,存钥匙的技术还是cookie,所以说session技术是基于cookie的。
在这里插入图片描述

2.1 php操作session

1. php新增session

//一定要先调用此函数开启session
session_start();
//通过超全局变量添加一条session记录
$_SESSION['名']=;

2. php删除session

// 开启session
session_start();

// 删除保存的session
// 删除变量的值
unset($_SESSION['name']);

3. php修改session

// 开启session
session_start();
//修改
$_SESSION['name'] = 'rose';

4. php查询session

//一定要先调用此函数开启session
session_start();
//直接通过超全局变量可以取到session记录
var_dump($_SESSION);
//单独取出某条$_SESSION记录
echo $_SESSION['name'];

2.2 nodeJS操作session

const session = require('express-session')
// 使用session的组件 
// 集成session中间件  req.session.xxx = yyy   req.session.xxx
app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true
}));

app.get('/awesome', function(req, res){
     
    if(req.session.lastPage) {
         console.log('Last page was: ' + req.session.lastPage + ".");    
     }    
    req.session.lastPage = '/awesome';
    res.send("You're Awesome. And the session expired time is: " + req.session.cookie.maxAge);
 });

三 cookie与session总结

session可以借助cookie实现状态维持,也可以不依赖cookie(URL重写)

在这里插入图片描述

3.1 cookie的不可跨域性:

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。

需要注意的是,虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。而session对于整个网站都是有效的.

四 localStorage的优势

1、localStorage拓展了cookie的4K限制

2、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的

4.1 localStorage的局限

1、浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性

2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换

3、localStorage在浏览器的隐私模式下面是不可读取的

4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡

5、localStorage不能被爬虫抓取到

localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

4.2 实例:实现localStorage的增删查功能

页面代码:

<input type="search"  id="search-input" placeholder="请输入你想比价的商品">
         <div class="search-history">
             <ul>
                 <!-- 这里放li标签 -->
             </ul>
         </div>
 <button id="search-btn">搜索</button>   

操作localStorage的JS代码

var search = {

	//添加localstorage的方法
	addlocalStorage :  function () {
		var that = this;
		$('#search-btn').on('click',function(){

			var searchContent =  $('#search-input').val(); //搜索框里的内容
			//判断搜索框里的内容是否为空,如果为空不添加到localstorage不继续下面的操作
			if(!searchContent) {
				//内容为空
				return false;
			}

			//获取浏览器localstorage中键名为searchHistory中的数据
			var historyData = localStorage.getItem('searchHistory'); 
			if(!historyData) { 
				//因为一开始就没有这个searchHistory键名所以获取到为空,此时将historyData赋值为空数组
				historyData = [];
			}else {
				//不为空,那么键名存在,数据也存在并且是字符串,现在转化为数组
				historyData = JSON.parse(historyData);
			}	

			//判断搜索的内容是否重复
			if(historyData.indexOf(searchContent) != -1) {
				//如果有删除原来的内容,再作为第一个元素添加在数组前
				historyData.splice(historyData.indexOf(searchContent),1); //删除
				historyData.unshift(searchContent); //添加
			}else {
				//如果没有,直接作为第一个元素添加在数组前
				historyData.unshift(searchContent);
			}
			//将数据添加到键名为searchHistory中localstorage中的数据,不过又要把数组转成字符串
			localStorage.setItem('searchHistory',JSON.stringify(historyData));

			//调用查询历史记录的方法
			that.queryHistory(); //在这里调用的意思是我搜索后就渲染到页面,可以不加
			//清空下拉框里面的数据
			$('#search-input').val("");
		});
	},

	//查询localstorage的方法
	queryLocalStorage : function(){
		//先取出来
		var searchData = JSON.parse(localStorage.getItem('searchHistory'));

		//循环遍历生成li标签
		var liHTML = "";
		for(var i=0;i<searchData.length;i++) {
			//searchData里面有没有数据
			if(searchData[i]) {
				var str = '<li>'+ searchData[i] +'</li>';
				liHTML += str;
			}
		}
		//在页面上的操作渲染li
		//doSometing.......
		//给输入框一个成为焦点事件
		$('#search-input').on('focus',function(){
			$('.search-history ul').html(liHTML);
			//再给li一个点击事件
			$('.search-history ul li').on('click',function(){
				$('#search-input').val($(this).text());
				$('.search-history ul').hide();
			});
		});	
	},
	
	//删除历史记录
    deleteHistory : function () {

          var that = this;            
          $('.content ul').on('tap','i',function() {
              
              //获取被点击的索引id
              var index = $(this).data('id');
              //获取当前本地存储的数组 把当前索引的值删掉
              var historyData = JSON.parse(localStorage.getItem('historyData')) || [];
              historyData.splice(index, 1);
              //删除完成后存储到本地存储中 把数组转成字符串
              localStorage.setItem('historyData', JSON.stringify(historyData));
              //查询新的历史记录
              that.queryHistory();
          }); 
      },

      //清空历史记录
       clearHistory : function () {
           var that = this;
           $('.clearTrash').on('tap',function(){
               //2. 调用本地存储removeItem 删除某个键和值
               localStorage.removeItem('historyData');
               // 3. 在清空完成后调用查询刷新页面
               that.queryHistory();
           });         
       }
}

//调用添加localstorage的方法
search.addlocalStorage();
//调用查询localstorage的方法并渲染到页面
search.queryLocalStorage();
//调用方法,删除历史记录
search.deleteHistory();
//调用方法,清空历史记录
search.clearHistory();

五 vuex配合localStorage增删改

5.1 技术简介

因为在实际操作中,vuex作为一个内存版的管理数据的仓库,当页面一刷新所有的数据都将变为初始值;所以我们可以将数据将存储在localStorage,我们vuex只管在初始化的时候或则数据变化的时候从localStorage获取数据就行了.

5.2 案例

整体需求:

  1. 就是其他组件改变了商品的数量,都要在我的根组件里面显示出来.

技术实现:

  1. 因为涉及到多个组件的传值,如果用"prop down,event up"是远远不能满足需求,同时也会让逻辑更加复杂,所以用到了vuex来全局管理我们的购物车数量buycount
    在这里插入图片描述
  2. 但是vuex的存储是内存版的,即页面重新加载后数据就会初始化;为了避免这个缺点,我们将所有的数据存到本地的localstorage中,vuex只需要做一个中间的桥梁
    在这里插入图片描述

具体业务代码:

因为涉及到两个模块,所以我们抽取为不同的两个模块出来:

  1. localStorage.js : 操作localstorage的增删改模块
  2. store.js : 操作vuex的存入数据,读取数据的模块

store.js模块

//store.js模块
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//按需引入操作LocalStorage的模块
import { addLocalStorageItem,totalBuyCount,updateLocalStorageItem,deleteLocalStorageItem } from "../common/localStorage.js"

//创建一个仓库
const store = new Vuex.Store({
    state : {
        buyCount : 0, //购物车商品总数
    },
    getters: { //获取仓库中的数据
        getTotalGoodsNum(state){
            /**
              1) 因为页面一刷新,此时的state.buyCount重置为0,然而,localstorage中存储的购买商品的
             总数据是存在的,所以需要假设:如果state.buyCount === 0先去查询localstorage中存储
             的购买商品的总数据返回给他,此时view更新.

              2) 添加购物车被点击了,state.buyCount在mutations里面变化了,state.buyCount !== 0
              此时直接返回state.buyCount当前的值.
             */
            return state.buyCount === 0 ? totalBuyCount() : state.buyCount
        },
        getWantVisitPath(state) {
            return state.wantVisitPath
        }
    },
    mutations: { //存入数据到仓库
        /**
         * 添加购物车信息
         * @param {*} state 
         * @param {*} goods 约定的载荷 
         * goods { goodsID : 91, count: 2 }
         */
        addShopCart(state,addGoods){
            //添加数据,将数据存入localstorage中,将更新后的数据返回
            state.buyCount = addLocalStorageItem(addGoods);
        },
        //更新购物车信息
        updateShopCart(state,updateItemGoods){
            //更新数据,将更新后的数据返回
            state.buyCount = updateLocalStorageItem(updateItemGoods)
        },
        //删除购物车数据
        deleteShopCart(state,delGoodsId){
           //删除数据,将删除后的数据返回
           state.buyCount = deleteLocalStorageItem(delGoodsId) 
        },
    },
});


//导出仓库,在main.js里面注入
export default store

localStorage.js模块

//localStorage.js模块
const key = "GOODS";
/**
 *  获取localstorage里面的值 { 90 : 3}
 * @param {*} key  键名
 */
const getLocalStorage = ( key = "GOODS" )=>{
    return JSON.parse(localStorage.getItem(key) || '{}')  
}

//获取总共的buycount
const totalBuyCount = ()=>{
    
    const localGoods = getLocalStorage(key); //获取本地存储的数据
    let totalCount = 0;
    for( var key in localGoods ) { //遍历本地储存的数据
        //将后面的键值加起来
        totalCount += localGoods[key]; 
    }
    return totalCount
}

//增加记录 
const addLocalStorageItem = goods => {

    //1. 从localstorage里面取出item值判断
    const localGoods = getLocalStorage(key) //这里传值亦可以不传亦可以
   
    //2. 判断是否有这个item,有就在和面覆盖键值,没有就加上去
    // goods { goodsID : 91, count: 2 }
    if(localGoods[goods.goodsID]) { //这里是利用[]来取对象的键值
        //有,计算覆盖前面的item的键值
        localGoods[goods.goodsID] += goods.count
    }else {
        //没有的话,就重新添加
        localGoods[goods.goodsID] = goods.count
    }

    // 3.把对象转成字符串,覆盖保存回去
    localStorage.setItem(key,JSON.stringify(localGoods))

    // 4.重新统计一下localStorage中最新的数量,返回
    return totalBuyCount();
};

//更改记录
const updateLocalStorageItem = updateGoods => {
    // console.log(updateGoods) {goodsID: 88, count: 2}

    //1. 从localstorage里面取出item值
    const localGoods = getLocalStorage(key) //这里传值亦可以不传亦可以

    //2. 更新对应的item的值
    localGoods[updateGoods.goodsID] = updateGoods.count

    // 3.把对象转成字符串,覆盖保存回去
    localStorage.setItem(key,JSON.stringify(localGoods))

    // 4.重新统计一下localStorage中最新的数量,返回
    return totalBuyCount();
};

//删除记录
const deleteLocalStorageItem = delGoodsId => {
    //console.log(delGoods)  //goodsID: 88

    //1. 从localstorage里面取出item值
    const localGoods = getLocalStorage(key) //这里传值亦可以不传亦可以

    //console.log(localGoods.delGoodsId) 这种方法是错误的,因为不能直接点
    //2. 删除对应的值
    delete localGoods[delGoodsId]

    // 3.把对象转成字符串,覆盖保存回去
    localStorage.setItem(key,JSON.stringify(localGoods))

    // 4.重新统计一下localStorage中最新的数量,返回
    return totalBuyCount();
}

export {
    addLocalStorageItem,
    totalBuyCount,
    getLocalStorage, //获取LocalStorage的数据
    updateLocalStorageItem,
    deleteLocalStorageItem
};

其他组件获取buycount的操作

this.$store.getters.getTotalGoodsNum 

组件提供增删改数据的操作

this.$store.commit('addShopCart',addGoods) //增
this.$store.commit('deleteShopCart',id) //删
this.$store.commit('updateShopCart',goods) //改
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值