一、项目结构目录

项目属于SPA (Single Page Appllication)单页面应用

  • iframe 基于iframe 页面嵌套(父页面嵌套子页面)模拟出 SPA 效果,但是他的本质还是多页面开发
  • AMD (require.js)/ (sea.js): 基于最初的模块化思想,我们把每一部分功能开发成为组件,最后让所有的组件都在同一个页面中,基于不同操作控制组件的显示隐藏
  • 前端路由:HASH 路由和 BROWSER 路由

vue-router / react-router-dom

1. 流程

  1. 首先跑环境: $ npm i

  2. 纠正一基础的配置:config.js
    port 后台程序运行的端口
    cors.allow_origin 客户端运行的服务地址

  3. 启动服务: $ node server.js

  4. 启动后的运行窗口不能关闭,关闭则后台服务器结束

2. 后台技术栈

admin 存储我们所有的后台程序,后台采用的技术栈

  • node
  • express / express-router
  • 当前项目采用 json 文件存储数据
  • session

3. 前端技术栈

client 存储客户端(前端)所有的程序,客户端采用的技术栈

  • HTML5 / CSS3 会用到字体图标
  • jQuery
  • AXIOS
  • 辅助插件:jquery.cookie / md5 / 自己写的一些方法
  • 基于 iframe 构建最初版本的 SPA 单页面应用开发

二、两种存储方式

1. 本地存储

本地存储:把信息存储到客户端本地 cookie
H5 中的 webStorage:localStorage / sessionStorage
本地数据库存储:IndexDb
本地缓存存储:mainfest

cookie

cookie 可以和 localStorage、sessionStorage 一并用作本地存储;但是cookie 主业不是做本地存储,它是用来保存 http 状态

HTTP协议是无状态的:即服务器向客户端发送数据结束后,连接就会关闭,而服务器不会记录发生的这一切;这就会有一个问题,如果我们登录后向服务器请求了一次资源,等服务器响应结束就会连接断开,但是我们第二次请求一个其他的资源,但是服务器已经忘记了你已经登录过,所以服务器要求你重新登录,这就导致每次请求东西都要登录;

为了解决这个问题,http 协议发明了cookie;cookie 是 http 协议的一部分,既不属于客户端技术也不属于服务端技术;但是客户端和服务端都有操作 cookie 的技术;

cookie 是存在客户端的,但是客户端和服务端都可以操作 cookie;在客户端发起请求的时候,http 协议会从客户端把所有的 cookie 读取出来,然后带着这些 cookie 去请求服务器;服务器收到请求后,服务器收到请求里面是包含 cookie 的,服务器就可以任意操作 cookie了。服务器响应的时候会让 http 协议把 cookie 再带给客户端(浏览器检测到响应中有 cookie,浏览器会自动把 cookie 保存起来)

以登录为例,第一次我们带着用户的用户名和密码去请求服务器,服务端拿到用户名和密码去数据库中匹配,如果匹配成功就成功登录,于此同时服务端会在 cookie 中设置一个值表示登录成功,等响应的时候这个 cookie 就会带到客户端,浏览器会自动把它存起来;下一次再请求的时候,http 协议会自动带着 cookie 去请求;

  1. // 浏览器操作 cookie:
  2. // 1. js 获取 cookie -> document.cookie
  3. console.log(document.cookie);
  4. // 2. js设置cookie -> document.cookie = 'key=value;配置属性'
  5. // document.cookie = 'name=mabin;';
  6. document.cookie = 'title=宇宙集团军总司令;';
  7. console.log(document.cookie);
  8. // document.cookie = 'name=bingo;';
  9. // 设置 cookie 时的注意事项:
  10. // 1. 如果设置多个,就需要多次给 document.cookie 赋值
  11. // 2. 如果同名 cookie,后面的会覆盖前面的;
  12. // cookie 的配置属性:
  13. // domain 可以访问这个 cookie 的域是哪个
  14. // path 可以访问当前 cookie 的路径,一般设置为 / 表示根目录;所有根目录下面的路径都能访问这个 cookie;
  15. document.cookie = 'name=bingo;path=/'; // 如果同名 cookie 配置属性不同不能互相覆盖;
  16. // expires cookie 的过期时间;cookie 是有时效性的,如果过期,浏览器就会删除这个 cookie;expires 的值是一个 GMT 时间;
  17. // 删除 cookie 的原理:把 cookie 的 expires 设置为一个过去的时间,浏览器会自动删了它;
  18. document.cookie = 'age=18;expires=Sat, 13 Jul 2019 08:53:00 GMT;';
  19. // maxAge: cookie 的有效期,表示 cookie 在多长时间之内是有效的,如1小时,1分钟;单位是 ms;(服务端设置的)
  20. // http-only: 只能给 http 协议使用,前端不能获取也不能修改;(服务端设置)

2. 服务器存储

服务器存储:把数据存储在服务器端
数据库存储:SQLSERVER / MYSQL / ORACLE / MODGOOB…
REDIS
SESSION:服务器存储

session 是什么

服务端技术,就是会话控制。
和 cookie 不同,cookie 是存在客户端的,而 session 是存在服务器上,并且不会随着 http 传递,cookie 可以在客户端随意被更改,服务器为了杜绝这种事情,服务器也搞了一个存储用户信息的东西,并且这个东西只在服务器放着,不给别人看,这个东西就是 session

session 的原理

以登录为例,登录时客户端会把用户名和密码发给服务器,服务端收到请求后回去数据库中匹配,如果匹配成功,就可以登录成功了,接着服务端会在 cookie 中设置一个表示登录状态的值,例如 isLogin = true; 同时服务器会生成一份 session 文件,这个 session 文件有一个 id,这个 id 叫做 session—id。这个 session 文件一般会用于存储用户的 id,登录时间等信息;然后把 session-id 会写到 cookie 中;然后 http 协议会带着这些 cookie 响应给客户端。
客户端收到响应后,会自动把响应中的 cookie 存储在浏览器中,这些 cookie 就包含了 session-id;
等再次发起请求时,http 协议会带着所有的 cookie 去请求,服务端收到请求后从 cookie 中找到 session-id 然后根据 session-id 去查找 session 文件,然后从 session 文件中获取用户的信息,如果信息有效就继续响应请求,否则认为登录失效

区别

session 和 cookie 的区别:

  1. session 是服务端技术,session 存在服务器上;
  2. cookie 是 http 协议的一部分,存在客户端;

session 和 cookie 的联系:session-id 是存 在cookie 中的,会随着 http 通信时在客户端和服务端来回传递;

token

token: 叫做令牌,不是和 cookie 或者 session 一样的一种技术,是一种用于身份校验机制; sign: 签名
token: 一般用户登录的时候,客户端会传递用户的用户名和密码给服务端,服务端匹配后,会根据用户 id、登录时间等信息生成一个字符串,并且还要给这个字符串加密,甚至还需要签名;
生成 token 以后会返回给客户端,客户端下次再请求的时候要带着这个 token 来,服务器就会认识这个 token,接着对 token 进行校验,如果通过继续响应,如果不通过就返回错误,要求用户重新登录;

常见的 token 使用方式:

  1. 把 token 放到 cookie 中,http 请求时会自动带着 token
  2. 服务端把 token 作为数据返回客户端,客户端需要手动保存 token;可以存在 localStorage 中,下次再请求的时候要把 token 从 ls 中取出来,再作为参数发送给服务端;
  3. 服务端返回 token 后,可以把 token 放到请求头里面,让服务端从请求头里面取;

和服务端同事沟通确定用哪种方式传递 token;

3. 什么时候用本地存储?作用?

  1. 记住用户名和密码(或者自动登录)

  2. 未登录状态下,加入购物车的信息一般也先存储在本地,当登录后,把信息存储到服务器上(目的是多平台数据共享)

  3. 对于非实时刷新数据我们可以在从服务器把数据获取到后,临时存储在本地(设置有效时间),在有效时间内,页面刷新不再重新获取数据,超过有效时间重新从服务器拉取(前端性能优化的一点)

  4. 还能实现同一个网站不用页面之间的信息共享和通信

4. 存储在哪了?

本地存储收到浏览器限制,如:在谷歌中存储的数据,在 ie 中获取不到,受源(域)的限制,例如:都是用谷歌浏览器,我在京东下存储的数据,在百度中是获取不到的
本地存储的信息在控制台中可以查看到(而且是明文存储)所以敏感的数据尽可能不要存储在本地,非要存储也要做安全处理(加密)

一些方法:

setItem([key],[value])存储信息 getItem([key])获取信息 removeItem([key]) 移除某一项信息 clear() 清除所有存储的信息

向本地存储信息都是字符串格式,如果不是字符串格式 ,localStorage 是持久化存储在客户端本地的,(除非手动清除或者浏览器卸载,否则一直存储下来,没有过期时间, 而 sessionStorage 是会话存储,当前页面刷新,存储信息还在,但是只要页面一关闭,所有会话存储的信息都会消失

三、什么是本地存储

设置 cookie -> jquery.cookie.js

  1. // 语法
  2. document.cookie = "[key] = [value]"
  3. // 过期时间
  4. expires:new Date(new Date().getTime() + 30 * 24 * 60 * 60 * 100)

1. cookit vs localStorage

  1. 大小限制,一般浏览器允许同一个源下 cookie 最多存储 8KB , 而 localStorage 被允许存储最大的长度限制是 5MB

  2. 兼容性:cookie 兼容所有浏览器,而 localStorage 是 H5 新增的,不兼容 ie 低版本浏览器(IE6-8)

  3. 稳定性:cookie 有过期时间,但是一般不等到过期时间就没了,例如:清除浏览器的缓存或者历史信息,还有安全卫士在清理电脑垃圾等操作时,都有可能把 cookie 清除掉。但是这些操作对 localStorage 没有影响。

  4. 有时候浏览器会开启无痕浏览模式或者隐私模式,此时无法设置 cookie ,但是可以设置 localStorage 的信息

  5. 和服务器的猫腻:cookie 总是会和服务器中的 session 眉来眼去,(客户端和服务器端交互的时候,cookie 信息传来传去),而 localStorage 不屑于和他们同流合污。(localStorage 和服务器没有必然联系,是单纯的本地存储)

  6. 存储时间:cookie 有过期时间,而 localStorage 是持久存储。

2. 关于信息加密

  1. 可逆转加密:按照规则加密,再按照规则解密,电话是可逆转的

  2. 不可逆转加密:一旦加密不能再解密 MD5 ,所以密码一定是不可逆转的

  3. 增加用户的时候,把用户密码进行 MD5 加密,把加密的结果存储到数据库中登录的时候,把输入的密码还是 MD5 加密,用加密的结果和之前存储的结果进行匹配,如果一样,则说明两次输入的原始密码是一致的

  4. 为了防止用户输入的密码过于简单,可以限制设置密码的规则,我们服务器端需要把 MD5 加密的结果进行二次或者多次加密(例如 MD5 加密的结果是32位,去掉前四位和后四位,把剩下的反序)

四、登录态及校验

  1. 在服务器设置一个 session(connect_sid),存储当前用户已经登录了

  2. 获取当前用户能操作的权限信息,连同登录成功的信息一并返回给客户端

  3. 服务器校验登录态只需要查看是否有 session 信息

  4. 如果我们在服务器端设置了 session 则会生成一个和当前客户端建立连接的唯一标识 connect_sed

  5. 当服务器在给客户端返回消息的时候,会把这个标识通过响应头 set-cookie 传递给响应头,客户端浏览器拿到信息后,只要发现响应头中有 set-cookie ,就会在客户端本地中一个不可修改性的 cookie 信息,存储的信息就是 connect_sid

  6. 以后客户端再向服务器发请求,浏览器会默认的在请求头中,把存储的 connect_sid 传递给服务器,服务器拿到请求后,就知道那个是客户端了,从而找到之前存储的 session 信息。服务器设置 session 的过期时间,一般和客户端的 cookie 的存储时间是一致的

五、iframe

有时候我们需要在页面里嵌套其他页面:

  1. iframe语法:<iframe src="https:www.jd.com" frameborder="0"></iframe>

基于 iframe 框架,可以在父页面中嵌入子页面,src 的地址就是要嵌入子页面的地址,当然也可以防嵌套

六、权限校验

权限校验从用户登录成功开始,权限校验最好不是控制元素的显示隐藏,而是控制真正的有或者没有

1. 客户端校验

当用户登录成功,服务器会把该用户所拥有的权限,返回给客户端;或者客户端可以基于某个 api 接口从服务器获取权限

  1. 客户端根据获取的权限校验标识,控制那些显示那些隐藏;或者进行某些操作之后,进行对应的提示

  2. 在某个页面中获取的权限校验码,需要在其他页面使用 -> 我们一般是基于本地存储完成的;在 vue / react 中是存储到 redux / vuex 中的。如果服务器支持获取权限的接口,也可以每次都从服务器重新获取

  • 弊端:因为是客户端本地校验;有可能还要把信息存储在客户端本地,容易导致权限校验码的泄露和篡改,不是很安全 -> 所以真是项目中对于重要的操作权限,服务器会进行二次校验。客户端每次吃业务逻辑请求的时候,服务器就做了校验
  • 优势:不需要频繁向服务器发送请求,获取校验码之后,一切判断由客户端处理,这样减少业务逻辑的复杂度,也减轻了服务器的压力,而且每次验证是否存在权限的速度也快

2. 服务器校验

  1. 客户端进行某个操作,服务器根据登录者的角色,进行权限校验,返回给客户端是否可以操作

  2. 服务器返回能否操作的标识,或者不确定那些内容可以看的,都向服务器发请求,由服务器告知我们,那些是需要展示的

  • 弊端:服务器要处理的请求和对应的压力较大
  • 优势:安全