前言

前面几篇文章填完坑之后,基本上我要做的基本流程是通的了,可以登录,可以传文件,可以显示识别结果。
然后接下来,是不是每次都要登录呢?没有登录肯定不能访问后面的URL地址,要主动跳转到登录页。而http协议是一个无状态的协议。也就是说,每次的request和response都和之前的无关。而在web应用中,太多的场景需要应用上下文内容了,数不胜数。那么,这些东西的实现就要用到session这个概念了。

HTTP中的session

提及session,首先就需要澄清下session的概念:

  1. 在web应用中,一般是指从一个浏览器窗口打开到关闭这个期间 ,我们可以称之为一个会话(SESSION,用大写来描述)。
  2. 或者可以指一类用来在客户端与服务器之间保持状态的解决方案 (session,用小写来描述)

一个会话(SESSION)一般来说有如下几个基本组成部分:

  1. 会话的建立和销毁
  2. 有效时间
  3. 有效时间内的上下文内容保存
    在web应用中,SESSION的建立和销毁是比较明确的(URL在窗口中打开和关闭),那么基于这个时间窗口,很多的session解决方案就用于解决后面这两个问题
    关于会话的标准可以参考:W3C规范 RFC6265

session方案

那么,要在基于HTTP协议的web应用中维护一个SESSION会话,就需要从上面的几个基本组成部分入手,那么解决方案就五花八门了。
从会话的信息保存位置来分的话,可以分成cookie和session两种方式。

协议支持

为了支持会话保持,上述的标准在http request header里增加了一个字段:cookies
HTTP Header
增加了一个头部字段名:Cookie。可以看一下这个XHR:
Header中的Cookie字段
后面提到的Cookie都是基于这个字段在做文章。

cookies

把维护SESSION上下文的信息保存在客户端,大致的过程如下:

  1. 客户端在第一次访问URL时,服务器创建一些参数信息在response中返回给客户端
  2. 客户端将这些参数保存在本地硬盘上
  3. 客户端浏览器继续访问这个URL的时候,将保存在客户端硬盘上的某些和这个URL相关的参数在请求中传给服务器端
  4. 服务器可以根据这些信息区分出访问来自于哪个会话SESSION了。
  5. 浏览器根据什么内容判断带哪些cookies,我感觉应该是根据URL,和跨域问题里的三部分一样,也就是协议+IP+PORT,这个还不是很清楚。不知道是有什么规范还是每个浏览器可以有不同的玩法。
  6. cookies有效时间的话,可以由服务器控制(cookie的过期时间),也可以由本地浏览器控制(过期删除,过期后重新登录获取新的cookie值)

VUE中的cookies操作

我用的是vue-cookies,用起来很简单

  1. 首先就是安装: npm install vue-cookies --save-dev

  2. 在main.js中添加:

     import vue-cookies from 'vue-cookies'
    
     Vue.use(vue-cookies)
    
  3. 在组件中就可以直接使用了,比如现在某个函数中设置一个cookie内容,都是key-value形式的:

     this.$cookies.set('key1', ‘abc’)
    

    浏览器就会将这个内容保存在本地,然后每次访问的时候就会带出来。我们可以在浏览器的开发者工具中看到:
    cookie内容展示

  4. 我们就可以在其他地方读取这个值了:

    let x = this.$cookies.get('key1')
    console.log(x)
    
  5. 典型场景:比如用户浏览过啥商品,我记录在cookie中,后面用户登录上来,我就可以直接重定向到这个商品页了。

  6. $cookies.config(new Date(2019,03,13).toUTCString())可以设置cookie的过期时间

session(token)

和cookie不一样,session维护SESSION的方式是将上下文的信息保存在服务器端,大致的过程如下:

  • 客户端在第一次访问URL时,服务器创建一个session对象并记录一些信息在这个对象中
  • 服务器端将session对象保存在内存中
  • 一般session信息会配合cookie一起使用,将一些关键信息设置到cookie中
  • 后续客户端的请求过来之后,服务器端可以将cookie的内容和session中的内容做比较,就知道是哪个会话的请求了。
  • 另外一个好处是,session可以将一些有用的上下文信息保存在seesion内存中,可以大大增加相应速度(不需要再次访问硬盘)。
  • 如果是大量连接的情况下,session会占用大量内存,需要一些算法来释放某些session以避免内存耗尽。

VUE-session操作

我用的是vue-cookies,用起来很简单

  • 首先就是安装: npm install vue-session–save-dev

  • 在main.js中添加:

     mport vueSession from 'vue-session'
    
     Vue.use(vue-session)
    
  • 在组件中就可以直接使用了,比如现在某个函数中设置一个session内容,都是key-value形式的:

     this.$session.set('key1', ‘abc’)
    

    在浏览器中可以看到:
    session内容
    和cookie不一样的是,这里保存了sessionID。而且如果关闭掉这个界面再重新进入,session里面的内容在客户端就被清除了,而cookie是会保存在本地硬盘的(所以有些内容需要写入到cookie中配合使用)

  • 我们就可以在其他地方读取这个值了:

    let x = this.$session.get('key1')
    console.log(x)
    
  • 典型场景:比如登录时,客户端使用用户名和密码登录后,后台服务器可以使用 MD5(username + password + timpstamp)来生成一个串作为token,然后用cookies.set将这个值保存在客户端,而浏览器会将这个cookie在每次访问中带上来,我们在一些关键的场景,比如跳转验证是否已登录等就可以校验这个值了。而且在浏览器关闭之后,还可以进行自动登录知道失效。

URL重写

很多浏览器中出于安全和隐私保护的考虑,会提供一个选项:
cookie选项
如果用户选择关闭的话,那么浏览器就会在发送request请求的时候不在header中增加cookie内容,我们就无法使用上面说到的方案去进行会话保持了。这时候就可以用到另一个方案:URL重写
URL重写和服务器本身配置有关,也是一个比较大的话题,后续研究了之后再进行补充吧。

浏览器存储

前面看cookie和session的时候,我们可以看到F12开发者工具中有很多的存储器:
浏览器存储器
刚才已经提到了Session Storage和cookie,从这里可以看出是基于域名来区分的。这里简单记录下其他几个东西:

Local Storage

Local Storage:在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。

localStorage的优势
  • localStorage拓展了cookie的4K限制

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

    localStorage的局限

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

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

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

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

  • localStorage不能被爬虫抓取到

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

localStorage使用

localStorage是顶层对象window下面的成员。
设置:

let storage = window.localStorage
storage.a = 1  //method 1
storage['a'] = 1 //method 2
storage.setItem('a', 1) //method 3

和Cookie一样,后续浏览器会带过来,就可以直接使用了。

let z = window.localStorage.a
console.log(z)

IndexedDB

cookie的大小不超过4KB,然后出了一个localStorage,存储量增加到了几MB。随着前端越来越复杂,需要的数据越来越多,所以,前端的数据库都跑出来了,也就时indexedDB:
indexedDB基本操作
我只简单的试了一下创建数据库,indexedDB也是window顶层对象下的成员进行操作:
打开数据库
其他操作懒得去试,因为我暂时也不会用,后续再研究吧。

Web SQL

因为我用的是chrome,所以可以看到这个东西,这个也是一个存储本地数据的数据库,和indexedDB类似。
就不仔细说了,大家网上一搜一大把内容。

VUE中的两个问题

vue.use

我们使用很多vue组件的时候,有的可以直接:

import axios from 'axios'

引入后就可以直接使用了:

axios.post()

但是有点东西,像vue-cookies/vue-session等组件就需要调用一下Vue.use方法。像搞懂这是为什么。找了一圈后,我自己的理解是:

  1. 定义VUE组件时,可以实现一个installing方法(类似于组件全都继承一个基础类或者实现一个接口),如果在引用之后调用Vue.use后,那么就会统一调用这个组件中的installing方法。有点组件提供了这个方法,就需要use一下,如果没有,就不需要。

  2. 每个vue文件都可以视作为一个vue对象,但是我们只需要在main.js中直接使用Vue.use之后,所有文件都可以使用了,比如:

    Vue.use(vue-cookies)
    

其他文件就可以:

this.$cookies.set()

我理解Vue就是一个类的static方法,执行这个方法之后,所有类的实例都可以受到影响。而这个use方法调用组件的installing方法后,将cookies等对象放到类的static成员中。

vue对象与组件

因为看到main.js中存在一个VUE对象,而各个.vue文件被称为组件。在main.js中使用代码:

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

来创建一个vue对象。
而在.vue文件中均使用export default来导出组件内容。所以想了解下组件vue对象和main.js中显式创建的vue对象有什么关系。
网上关于这个话题最多的一段描述是:
没有实质性的区别,一个组件就是一个 vue 实例,只不过大多数情况下作为组件的实例是父级组件来初始化的。硬要说组件特殊的地方,无非是组件的 data 是一个方法,因为组件可以被生成多次,如果使用一个对象的话那么这个对象将被所有组件实例共享。
这里讲一下自己的理解:

  1. 在main.js中显式创建的对象,这个对象包含两个部分,渲染部分:template: '< App/ >'和逻辑部分:components: { App }
  2. 渲染部分和App.vue文件中的< template >部分对应,而逻辑部分与app.vue里面的 name = ‘app’的部分对应,然后通过底层框架将这两部分做了双向绑定
  3. 所以我的理解是components组件是整个VUE对象中的一个成员。
  4. 而上述的一段话可能指的是components和VUE对象都是同一种类,只是这种类可以嵌套。
    上面的话纯粹是自己为了理解这个逻辑而记录的,不一定对。看看后续如果有时间看VUE的源码再说吧。
Logo

前往低代码交流专区

更多推荐