Skip to content

Commit

Permalink
react相关
Browse files Browse the repository at this point in the history
  • Loading branch information
huyaocode committed Feb 25, 2019
1 parent a868ba1 commit ffe7f94
Show file tree
Hide file tree
Showing 33 changed files with 565 additions and 708 deletions.
102 changes: 95 additions & 7 deletions React/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,6 @@ key是React中用于追踪哪些列表中元素被修改、删除或者被添加
变量的作用域不同,less在全局定义,就作用在全局,在代码块中定义,就作用于整哥代码块。而sass只作用域全局。


### 高阶组件 HOC (higher order component)

高阶组件是一个以组件为参数并返回一个新组件的函数。

HOC 允许你重用代码、逻辑和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。


### react生命周期中,最适合与服务端进行数据交互的是哪个函数
`componentDidMount`:在这个阶段,**实例和dom已经挂载完成,可以进行相关的dom操作**
Expand Down Expand Up @@ -222,4 +216,98 @@ SSR带来的问题:

### 怎么阻止组件的渲染

在组件的 render 方法中返回 null 并不会影响触发组件的生命周期方法
在组件的 render 方法中返回 null 并不会影响触发组件的生命周期方法


### 前端路由原理
前端路由实现起来其实很简单,本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。目前前端使用的路由就只有两种实现方式。
- Hash 模式
- History 模式

#### Hash 模式

`www.test.com/#/` 就是 Hash URL,当 # 后面的哈希值发生变化时,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面,并且无论哈希值如何变化,服务端接收到的 URL 请求永远是 www.test.com。
```js
window.addEventListener('hashchange', () => {
// ... 具体逻辑
})
```

#### History 模式
History 模式是 HTML5 新推出的功能,主要使用 `history.pushState``history.replaceState` 改变 URL。

通过 History 模式改变 URL 同样不会引起页面的刷新,只会更新浏览器的历史记录。

```js
// 新增历史记录
history.pushState(stateObject, title, URL)
// 替换当前历史记录
history.replaceState(stateObject, title, URL)
```

当用户做出浏览器动作时,比如点击后退按钮时会触发 popState 事件
```js
window.addEventListener('popstate', e => {
// e.state 就是 pushState(stateObject) 中的 stateObject
console.log(e.state)
})
```

#### 两种模式对比
- Hash 模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL
- History 模式可以通过 API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串
- Hash 模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置 index.html 页面用于匹配不到静态资源的时候


### Vue 和 React区别
改变数据方式不同,Vue 修改状态相比来说要简单许多,React 需要使用 setState 来改变状态,并且使用这个 API 也有一些坑点。
Vue 的底层使用了依赖追踪,页面更新渲染已经是最优的了,但是 React 还是需要用户手动去优化这方面的问题。

React 需要使用 JSX,Vue 使用了模板语法



### 高阶组件 HOC (higher order component)

高阶组件是一个以组件为参数并返回一个新组件的函数。

HOC 允许你重用代码、逻辑和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。

```js
function add(a, b) {
return a + b
}
```
现在如果我想给这个 add 函数添加一个输出结果的功能,那么你可能会考虑我直接使用 console.log 不就实现了么。说的没错,但是如果我们想做的更加优雅并且容易复用和扩展,我们可以这样去做:
```js
function withLog (fn) {
function wrapper(a, b) {
const result = fn(a, b)
console.log(result)
return result
}
return wrapper
}
const withLogAdd = withLog(add)
withLogAdd(1, 2)
```
这个做法在函数式编程里称之为高阶函数,大家都知道 React 的思想中是存在函数式编程的,高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好的复用代码。


### 事件机制
React 其实自己实现了一套事件机制,首先我们考虑一下以下代码:
```js
const Test = ({ list, handleClick }) => ({
list.map((item, index) => (
<span onClick={handleClick} key={index}>{index}</span>
))
})
```

事实当然不是,JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的**事件都统一绑定在了`document`**。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。

另外冒泡到 document 上的事件也不是原生浏览器事件,而是**React自己实现的合成事件**(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。

那么实现合成事件的目的好处有两点,分别是:
- 合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力
- 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。
32 changes: 22 additions & 10 deletions Web安全/CSRF.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
# CSRF 跨站请求伪造
(Cross Site Request Forgy)
打开同一浏览器时其他的网站对本网站造成的影响。
打开同一浏览器时其他的网站对本网站造成的影响。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
![原理](../img/csrf.png)


举个例子,用户同时打开了A网站和钓鱼网站。 假设A网站中有一个通过 GET 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口。
```html
<img src="http://www.domain.com/xxx?comment='attack'"/>
```


## CSRF攻击原理
1. 用户登录A网站
2. A网站确认身份
2. A网站确认身份(给客户端cookie)
3. B网站页面向A网站发起请求(带上A网站身份)


## CSRF防御
1. Get 请求不对数据进行修改
2. 不让第三方网站访问到用户 Cookie
3. 阻止第三方网站请求接口
4. 请求时附带验证信息,比如验证码或者 Token

- SameSite
- 可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。
- Token验证
- cookie是发送时自动带上的,而不会主动带上Token,所以在每次发送时主动发送Token
- Referer验证
- 判断页面来源
- 对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。
- 隐藏令牌
- 主动在HTTP头部中添加令牌信息


禁止第三方网站带cookies

[same-site](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies#SameSite_Cookies)属性。 设置只有同一站点的请求才能携带cookie


## CSRF蠕虫
如果某个用户打开了被攻击网页,并且用户同时访问了攻击者的网页。
那么攻击者的网页就会使用用户的身份发送一些请求,并且常用用户的身份发布一些评论或文章,里面包含攻击者的网页链接。如果其他用户看到了这个用户的这条评论,都甚至可以不点击,其他用户也会被盗用身份发送一些恶意请求。这样病毒的传播就会越来越快,影响越来越大。
Expand All @@ -31,10 +49,4 @@
-
- 盗取用户资金
- 冒充用户发帖背锅
- 损坏网站名誉


## CSRF防御
禁止第三方网站带cookies

[same-site](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies#SameSite_Cookies)属性。 设置只有同一站点的请求才能携带cookie
- 损坏网站名誉
50 changes: 48 additions & 2 deletions Web安全/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
### 攻击类型
- [XSS](./XSS.md) 跨站脚本攻击
- [CSRF](./CSRF.md) 跨站请求伪造
- 点击劫持
- 中间人攻击


### 核心
Expand Down Expand Up @@ -37,6 +39,50 @@
参考链接: [浏览器同源政策](https://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html)


## 点击劫持

### CSP 内容安全策略
[CSP](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP) ( Content Security Policy ) 在http头中指定哪一些内容是可以执行的
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。

对于这种攻击方式,推荐防御的方法有两种。
- X-FRAME-OPTIONS
- JS 防御


### X-FRAME-OPTIONS
`X-FRAME-OPTIONS` 是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。

该响应头有三个值可选,分别是
- `DENY`,表示页面不允许通过`iframe`的方式展示
- `SAMEORIGIN`,表示页面可以在相同域名下通过`iframe`的方式展示
- `ALLOW-FROM`,表示页面可以在指定来源的`iframe`中展示


### JS防御
对于某些低版本浏览器来说,并不能支持上面的这种方式,那我们只有通过 JS 的方式来防御点击劫持了。
```html
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>
```


## 中间人攻击
中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。

通常来说不建议使用公共的 Wi-Fi,因为很可能就会发生中间人攻击的情况。如果你在通信的过程中涉及到了某些敏感信息,就完全暴露给攻击方了。

当然防御中间人攻击其实并不难,只需要增加一个安全通道来传输信息。HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击。
44 changes: 38 additions & 6 deletions Web安全/XSS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# XSS 跨站脚本攻击
![xss](img/xss.png)

XSS ( Cross Site Scripting )
XSS ( Cross Site Scripting ) 简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中。

XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。

从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
Expand Down Expand Up @@ -60,6 +61,13 @@ var data = "hello"; alert(1);"";


## XSS 防御

对于 XSS 攻击来说,通常有两种方式可以用来防御。
- 转义字符
- CSP 内容安全策略

### 转义字符

- 普通的输入 - 编码
- 对用户输入数据进行HTML Entity编码(使用转义字符)
- "
Expand All @@ -77,20 +85,20 @@ var data = "hello"; alert(1);"";
- 使用DOM Parse转换,校正不配对的DOM标签和属性


### 对于会在DOM中出现的字符串(用户数据):
#### 对于会在DOM中出现的字符串(用户数据):

< 转义为 \&lt;
> 转义为 \&gt;
### 对于可能出现在DOM元素属性上的数据
#### 对于可能出现在DOM元素属性上的数据

" 转义为 \&quot;
' 转义为 \&9039;
空格转义为 \&nbsp; 但这可能造成多个连续的空格,也可以不对空格转义,但是一定要为属性加双引号

& 这个字符如果要转义,那么一定要放在转移函数的第一个来做

### 避免JS中的插入
#### 避免JS中的插入
```js
var data = "#{data}";
var data = "hello"; alert(1);"";
Expand All @@ -101,7 +109,7 @@ var data = "hello"; alert(1);"";
再 " -> \\"
```

### 富文本
#### 富文本

按照黑名单过滤: script等
但是html标签中能执行html代码的属性太多了,比如onclick, onhover,onerror, <a href="jacascript:alert(1)">
Expand Down Expand Up @@ -144,6 +152,30 @@ function xssFilter (html) {
}
```

## 使用npm包来简化操作
#### 使用npm包来简化操作
[xss文档](https://github.com/leizongmin/js-xss/blob/master/README.zh.md)


### CSP 内容安全策略

CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。

通常可以通过两种方式来开启 CSP:
- 设置 HTTP Header 中的 Content-Security-Policy
- 设置 meta 标签的方式 `<meta http-equiv="Content-Security-Policy">`

以设置 HTTP Header 来举例
- 只允许加载本站资源
```
Content-Security-Policy: default-src ‘self’
```
- 图片只允许加载 HTTPS 协议
```
Content-Security-Policy: img-src https://*
```
- 允许加载任何来源框架
```
Content-Security-Policy: child-src 'none'
```

[CSP](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP) ( Content Security Policy )
Binary file added img/aduits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/aduitsReport.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/auditsSuggest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/performance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/vScroll.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ffe7f94

Please sign in to comment.