React Hooks 原理简析

说明 本文的原理简析基于 React 17.0.2 和 Legacy Mode ,不涉及 Concurrent Mode 。 函数组件与类组件 想要理解 Hooks,需要先理解函数组件与类组件之间的区别。 先看概括 React 设计理念的公式: 1 UI = render(data) React 根据状态渲染视图,且一个状态对应一个渲染结果。也就是说,数据是和渲染结果绑定的。 类组件与可变的 this 在 React 中,推荐使用不可变数据 (immutable data) 描述状态。需要更新状态时,应使用一份新的数据,而不是对原来的数据进行修改。 不过就算使用不可变数据,类组件中还是会有 this 的问题。先看一个类组件示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** 假设这里是某个用户的个人信息页 点击 Follow 将会关注该用户,关注成功后需要弹出消息,提示关注成功 通过 setTimeout 模拟了一个响应较慢的接口 */ class ProfilePage extends React.Component { showMessage = () => { alert('Followed ' + this....

2021年6月20日 · ruihusky

CSRF的原理与防御

CSRF 原理 CSRF 的全称是 Cross Site Request Forgery 的缩写,即跨站请求伪造。简单的说,当用户在被攻击网站未退出登陆时,攻击者欺骗用户在攻击者的网站请求了被攻击网站某一需要登录权限的链接,则构成 CSRF。 举一个经典的例子: 用户登录了某一家银行网站,其登陆状态由浏览器 cookie 与服务器 session 维持。该网站有一用于执行转账操作的 get 请求: https://bank.example.com/withdraw?account=AccoutName&amount=1000&for=PayeeName 攻击者在一个恶意网站上放置如下代码: <img src="https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman" /> 如果用户登录了银行网站之后还未退出登陆,并访问了恶意网站,则上述img标签会发出转账请求,并携带银行网站的登录态 cookie。服务器收到了请求,并查看 cookie,发现用户依然是登陆状态,则认为该次请求合法。于是用户的银行账户就损失了 1000 资金。 注意到,攻击者并不能通过 CSRF 直接获取用户帐户的控制权限,也不能窃取用户的任何信息。攻击者能做的是欺骗用户的浏览器,让其以用户的名义执行操作。 CSRF 防御 CSRF 具备两个特点: CSRF 通常是发生在第三方域名的 CSRF 通过欺骗浏览器来使用 cookie 中的信息,以获取用户权限来执行某些操作 针对这两个特点,我们可以制定对应的防护策略。 检查 Referer 字段 http 请求头中有一个 Referer 字段,用于标识该请求来源于哪个地址。如果是来自恶意网站的请求,则 Referer 字段将会是恶意网站的地址,服务器可以拒绝该次请求。服务器也可以设置为只允许来自于特定 Referer 的请求,相当于一个白名单规则。 这种方法实现简单,但也有其局限性。虽然 http 协议对 Referer 字段的内容有明确的规定,但无法保证浏览器的具体实现,也无法保证浏览器自身是否没有安全漏洞。使用检查 Referer 字段的方法,等于将安全性依赖于第三方浏览器实现。 CSRF token CSRF 中,攻击者只能利用 cookie 中的信息。我们可以要求所有的用户请求都携带一个攻击者无法获得的 token。原理是:当用户发送请求时,服务器端应用生成一个随机且唯一的令牌(token),并将其发送给客户端。客户端提交请求的时候,将 token 一起发送到服务端,服务端通过验证 token 是否有效来判断该次请求的合法性。...

2021年3月14日 · ruihusky

十大经典排序算法

概览与术语 在计算机科学与数学中,一个排序算法(Sorting algorithm)是一种能将一串资料依照特定排序方式进行排列的一种算法,最常用到的排序方式之一就是数值顺序。 排序算法依照稳定性可分为稳定算法和不稳定算法。稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录 R 和 S,且在原本的列表中 R 出现在 S 之前,则在排序过的列表中 R 也将会是在 S 之前。 排序算法依照排序过程中占用空间的方式分为 In-place 算法 与 Out-place 算法。In-place 是原地算法,基本上不需要额外的辅助空间,可允许固定数量的辅助变量。非原地算法就是 Out-place,其开辟的辅助空间与问题规模相关。例如,冒泡排序只需要数据在原序列中交换位置,不需要额外的辅助空间,是 In-place 算法。 不同的排序算法会有不同的时间复杂度(最差、平均、和最好性能),下表列出了十种经典排序算法的概览: 冒泡排序(Bubble Sort) 一种简单的排序算法。该算法重复地走访过要排序的数列,每次比较相邻的两个元素,如果它们的顺序错误就进行交换,直到序列有序。这个算法的名字由来是因为:越小/越大的元素会经由交换慢慢“浮”到数列的顶端。 冒泡排序对 n 个项目最多需要 O(n2) 的比较次数,且可以原地排序。尽管这个算法是最易了解和实现的排序算法之一,它对于大量数据的排序效率还是比较低。 算法描述 比较相邻的元素。如果第一个比第二个大,就交换他们两个; 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数; 针对所有的元素重复以上的步骤,除了最后一个; 重复步骤 1~3,直到没有任何一对数字需要比较; 可选的优化步骤:某次步骤 1~3 执行过程中没有元素发生交换,则证明该序列已经有序,不需要再进行下一次序列遍历。 动图演示 代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // TypeScript实现 export function bubbleSort(arr: number[]) { const len = arr....

2021年2月20日 · ruihusky

CSS flex-basis: auto 与弹性布局

flex 布局中的问题 最近在开发一个移动端适配的 H5 应用时,遇到了一个布局上的问题。简单描述如下: 页面从上到下排列有多个元素,其中有几张图片。在高宽比较大的手机上展示时(也就是比较长的手机,例如 iPhone X),布局没什么问题。但在一些小手机上,屏幕的纵轴无法容纳这么多元素。特别当微信浏览器中出现下方的导航栏时,高宽比被进一步减小,纵轴空间更加局促了。 这个问题看起来不难。使用 flex 布局,让图片元素在小屏幕上自动控制高度,自适应等比缩放不就 OK 了吗?于是写出了如下的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <div class="page-container"> <!-- ...其他flex子项 --> <div class="image-wrap"> <!-- 为了实现多个动画效果,图片被一个div包裹 --> <img class="image" src="..." /> </div> <!-- ...其他flex子项 --> </div> <!-- vue css scope --> <style> ....

2021年1月26日 · ruihusky

Unicode 编码与 UTF-32、UTF-16、UTF-8

字符编码与 Unicode 编码 字符,又或者说文本在计算机中是以字符编码的方式存储的。计算机以二进制处理信息,每一位只有 1 和 0 两种状态,每个字节就可以组合出2^8=256种状态(1 字节=8 位)。以 ASCII 为例,它用 7 位的二进制来表示字母、数字和其它符号编号,共计 128 个字符,通常会额外使用一个扩充的位,以便于以 1 个字节的方式存储。 Unicode 是一个庞大的字符编码集合,是一种用于展示世界上所有语言的字符的编码标准。在 20 世纪 80 年代开始启动设计工作时,人们认为两个字节的代码宽度足以对世界上各种语言的所有字符进行编码,并有足够的空间留给未来的扩展,理论上一共最多可以表示 2^16(即 65536)个字符。这 16 位统一码字符构成了基本多文种平面,其编码范围为 U+0000 ~ U+FFFF。 经过一段时间,Unicode 字符超过了 65536 个,基本多文种平面无法满足描述所有 Unicode 字符的需要了。为了扩展需求,Unicode 在原来的基础上新增了 16 个辅助平面,每个平面的编码范围为: 辅助平面 1:U+10000 ~ U+1FFFF 辅助平面 2:U+20000 ~ U+2FFFF … 辅助平面 15:U+F0000 ~ U+FFFFF 辅助平面 16:U+100000 ~ U+10FFFF 所有辅助平面的编码范围为 U+10000 ~ U+10FFFF,共计 16 个辅助平面,每个辅助平面最多可存储 2^16(即 65536)个字符,也可以说每个辅助平面都有 65536 个码位。 到这里为止,还只是 Unicode 的编码方式,下文简要说明其几种实现方式。...

2020年12月16日 · ruihusky