目录
- 写一个 react hooks + koa 风格的 web 框架
- 给 session 安排 useEffect 和 memo 会是种什么样的开发体验?
前言
迎着 react-hooks
的热度,我写了一个 React hooks + koa 风格的纯函数式 web 框架,目前已发布到 npm 上,有兴趣的可以去我的 github 上查看 源码。
一、科普
session
和 cookies
是 web 开发绕不开的话题,因为 http 是无状态的,从同一客户端发出的请求,其实服务端是无法识别是否同一客户端发起的,这样就导致如果没有一个明确的身份标示,那就会存在一种 “请证明你是你自己”
的尴尬情况。
之所以存在无法识别的情况,原因是互联网的情况错综复杂,即使是 IP 地址,也无法证明你是你,因为从同一局域网发出的外网请求,获取到 ip 地址会是同一个。
那如何证明两次请求是同一个客户端发起的,而对于用户是无感知的呢?
这个就是今天的话题之一 cookies
的功劳,cookies
是存储在用户设备上的一个小型文本文件。
里面的内容浏览器会在每次请求的时候,通过 http 的请求头主动发送给服务端的,服务端接收到客户端的请求,从请求头中取出内容即可。
服务端也可以主动写入 cookies
,只要在响应的头上加上 Set-Cookie
的值,浏览器会自动更新客户端上的内容。
既然有了浏览器的主动上报,那对于用户来说是无感知的,而我们通过 Header
可以读取和设置内容,也就为证明 你是你,提供了有利条件。
但是 Cookies
存在诸多限制和缺陷,比较致命的缺陷就是 存储的大小限制 和 安全性,因为 Cookies
是存储在客户端的,也就是会存在 Cookies
被盗用的问题,安全方面无法得到保证。
那如何解决这两个问题?
这里就说到了这次的主角 Session
了,专业的 Session
和 Cookies
科普文章,互联网已经发布过非常多的文章了,这里仅说明两者是如何关联的。
session
都知道是存储在服务端的,其实就是在服务端开辟了一个存储区域,里面会根据 每一个客户端 的请求生成一个 sessionId
,然后根据这个 id 将值写入到存储区域,这个值就是我们说的 session
。
同时这个sessionId
会通过请求头写入到 Cookies
,那下次客户端带上这个sessionId
,我们就可以获取到上次针对这个客户端写入的值了 。
这里要强调 每一个客户端 的一点是,前面也说了 http 是无状态的,本次请求是无法和上一次请求进行关联的,也就是说,当你每次清空掉 cookies
,那再次发起的请求,对于服务端来说,就是一个新的客户端连接。
所以我们一般情况下都会为 session
添加存储时间限制,每次客户端请求都会重新设置这个时间,如果时间超过了,那 session
也就失效了。
二、开发一个 session 插件
session
需要 cookies
支持,这里我使用 cookies 插件,这个是 koa 内置的插件。
编写 useCookies 函数
编写 createSessionId 函数
编写 createSession 函数
编写 useSession 插件
这里安排上了 useEffect
,这个钩子会在请求结束后被调用,支持异步的。
这里仅仅模拟而已,缺少了时间限制的功能,我们以前 session
是存储到 redis
中的,所以可以使用 cookies
本身的 maxAge
和 redis
自身的过期机制解决这个问题
三、使用 session 的功能
因为就是纯函数,所以直接在路由回调中使用就可以了
上下文的介绍可以查看 写一个 react hooks + koa 风格的 web 框架 这片文章来了解,这里不多做解释。
我们可以看到这个就是一个函数调用,对于开发者来说,非常透明,减少了很多理解成本。
不过这里其实还有一个问题,那就是多次调用 useSession
会出现,重复处理的问题。
那如何解决这个问题呢?
这个时候我们就需要用到一个新的 api,那就是 memo
,我们来改造一个 useCookies
和 useSession
这两个钩子函数。
我们在这两个钩子函数外面包了一层,但是对于调用者来说,并无任何变化,仅仅是在调用过程中,做了缓存。
memo
缓存的结果,会在每次请求完成时候被清除,保证本次请求和下次请求不会出现混淆的问题。
结束
react-hooks
为我们打开了编程的新大门,以前一直以为没了构造函数,插件就写不下去了。
但是现在,纯函数的编程,比构造函数更加透明,唯一难点就是上下文的管理特别依赖底层,但是就编程来说,无疑为我们提供了一些新的思路和解决方案。
这对于编程的能力的提升,可以说帮助还是比较大的。