100、什么是 React Fiber?
Fiber 是 React 16 中新的协调引擎或重新实现核心算法。它的主要目标是支持虚拟DOM的增量渲染。React Fiber 的目标是提高其在动画、布局、手势、暂停、中止或重用等方面的适用性,并为不同类型的更新分配优先级,以及新的并发原语。
React Fiber 的目标是增强其在动画、布局和手势等领域的适用性。它的主要特性是增量渲染:能够将渲染工作分割成块,并将其分散到多个帧中。
101、如何在 ReactJS 的 Props上应用验证?
当应用程序在开发模式下运行时,React 将自动检查咱们在组件上设置的所有 props
,以确保它们具有正确的数据类型。对于不正确的类型,开发模式下会在控制台中生成警告消息,而在生产模式中由于性能影响而禁用它。强制的 props
用 isRequired
定义的。
下面是一组预定义的 prop 类型:
- React.PropTypes.string
- React.PropTypes.number
- React.PropTypes.func
- React.PropTypes.node
- React.PropTypes.bool
例如,咱们为用户组件定义了如下的propTypes
import PropTypes from 'prop-types';
class User extends React.Component {
render() {
return (
<h1>Welcome, {this.props.name}</h1>
<h2>Age, {this.props.age}
);
}
}
User.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired
};
102、在 React 中使用构造函数和 getInitialState 有什么区别?
构造函数和getInitialState
之间的区别就是ES6
和ES5
本身的区别。在使用ES6
类时,应该在构造函数中初始化state
,并在使用React.createClass
时定义getInitialState
方法。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { /* initial state */ };
}
}
等价于:
var MyComponent = React.createClass({
getInitialState() {
return { /* initial state */ };
},
});
103、如何有条件地向 React 组件添加属性?
对于某些属性,React 非常聪明,如果传递给它的值是虚值,可以省略该属性。例如:
var InputComponent = React.createClass({
render: function() {
var required = true;
var disabled = false;
return (
<input type="text" disabled={disabled} required={required} />
);
}
});
渲染结果:
<input type="text" required>
另一种可能的方法是:
var condition = true;
var component = (
<div
value="foo"
{ ...( condition && { disabled: true } ) } />
);
104、Hooks会取代 render props
和高阶组件吗?
通常,render props
和高阶组件仅渲染一个子组件。React团队认为,Hooks 是服务此用例的更简单方法。
这两种模式仍然有一席之地(例如,一个虚拟的 scroller
组件可能有一个 renderItem prop
,或者一个可视化的容器组件可能有它自己的 DOM 结构)。但在大多数情况下,Hooks 就足够了,可以帮助减少树中的嵌套。
105、如何避免组件的重新渲染?
React 中最常见的问题之一是组件不必要地重新渲染。React 提供了两个方法,在这些情况下非常有用:
React.memo()
:这可以防止不必要地重新渲染函数组件PureComponent
:这可以防止不必要地重新渲染类组件
这两种方法都依赖于对传递给组件的props
的浅比较,如果 props
没有改变,那么组件将不会重新渲染。虽然这两种工具都非常有用,但是浅比较会带来额外的性能损失,因此如果使用不当,这两种方法都会对性能产生负面影响。
通过使用 React Profiler,可以在使用这些方法前后对性能进行测量,从而确保通过进行给定的更改来实际改进性能。
106、什么是纯函数?
纯函数是不依赖并且不会在其作用域之外修改变量状态的函数。本质上,纯函数始终在给定相同参数的情况下返回相同结果。
107、当调用setState
时,React render
是如何工作的?
咱们可以将"render
"分为两个步骤:
- 虚拟 DOM 渲染:当
render
方法被调用时,它返回一个新的组件的虚拟 DOM 结构。当调用setState()
时,render
会被再次调用,因为默认情况下shouldComponentUpdate
总是返回true
,所以默认情况下 React 是没有优化的。 - 原生 DOM 渲染:React 只会在虚拟DOM中修改真实DOM节点,而且修改的次数非常少——这是很棒的React特性,它优化了真实DOM的变化,使React变得更快。
108、如何避免在React重新绑定实例?
有几种常用方法可以避免在 React 中绑定方法:
1.将事件处理程序定义为内联箭头函数
class SubmitButton extends React.Component {
constructor(props) {
super(props);
this.state = {
isFormSubmitted: false
};
}
render() {
return (
<button onClick={() => {
this.setState({ isFormSubmitted: true });
}}>Submit</button>
)
}
}
2.使用箭头函数来定义方法:
class SubmitButton extends React.Component {
state = {
isFormSubmitted: false
}
handleSubmit = () => {
this.setState({
isFormSubmitted: true
});
}
render() {
return (
<button onClick={this.handleSubmit}>Submit</button>
)
}
}
3.使用带有 Hooks 的函数组件
const SubmitButton = () => {
const [isFormSubmitted, setIsFormSubmitted] = useState(false);
return (
<button onClick={() => {
setIsFormSubmitted(true);
}}>Submit</button>
)
};
109、你怎样理解“在React中,一切都是组件”这句话
在 react 中,一个页面由往往由多个 component 组成,他们之间彼此独立,互不影响。而一个组件又可以由多个小组件组成。
另一种回答:组件是 React 应用 UI 的构建块的基本单位。这些组件将整个 UI 分成小的独立并可重用的部分。每个组件彼此独立,而不会影响 UI 的其余部分。
110、怎样解释 React 中 render() 的目的
用于更新 UI,比如当 state 的值被改变了的时候,render 会自动被调用到。render 中的 jsx 必须被封装到一个最外层元素中,
111、如何将两个或多个组件嵌入到一个组件中?
我觉得这道题很奇怪,把两个组件放到一个组件其实就在 render 里面直接用 jsx 排版就可以了。
render(){
return(
<div>
<Component1/>
<Component2 />
</div>
);
112、什么是 Props?
由父组件传过来的参数,是常量,不可修改。且只能父传子,不能子传父。
113、React中的状态是什么?它是如何使用的?
由组件自己控制,state 改变时会触发 render。component 中,假如你定义了一个变量,但你不想用它来触发 render,请把它定义成普通类变量。
114、区分状态和 props
状态是组件自己维护的,状态的改变会触发 render;props 不可以改变,是父组件传过来的。
115、如何更新组件的状态?
使用 this.setState(),直接修改 state 并不会触发 render()。
116、React 中的箭头函数是什么?怎么用?
箭头函数没有自己的 this,它里面的 this 属于调用它的 component。因此箭头函数中可以获取 component 的 props 和 state。
117、 区分有状态和无状态组件。
有状态组件一般是一个 class,无状态组件一般是一个 function
1、如何防止XSS攻击
一、xss攻击原理
大家想必都听过xss攻击,那么这个xss到底是如何攻击、我们又应该如何防范的呢?
xss攻击主要是针对表单的input文本框发起的,比如有这样一个文本框:
xss攻击图1
在说明一栏填入一段js代码,如果前端不进行过滤直接提交到后端(比如php),而php端也没有进行过滤直接入库,那么在下一个展示页面,就会发生这样的情况:
xss攻击图2
为什么会酱紫呢?
因为我们在说明这一栏的input,会将后端返回的内容直接追加进去,导致js代码执行。
可能有同学会不屑一顾:
你弹个框又能怎样呢?大不了我关了就是了呗!
那假设是cookie这样的敏感信息呢?我们不妨来做个试验:
xss攻击图3
执行代码:
xss攻击图4
这样就可以获取到一个用户的cookie了。那再进一步,如果把所有的cookie都想办法弄出来,然后存到自己的库里面的话。。。
想想挺带劲的哈,咱们不妨动手搞一下。
我们可以直接注入这样一段js脚本:
xss攻击图5
这段脚本呢,我就直接这么搞:
xss攻击图6
您别误会,我的本意不是创建一个图片,而是利用图片的src跨域属性,直接把cookie的值,传送到我的php后端代码里面,接下来就可以入库了哈哈~~
by the way,将图片的宽高设置为0,用户是不会看到这个图片的,因此这段js一旦注入生效,所有的用户都会触发这个js,从而将自己的cookie源源不断的输送到我的php代码中。
二、防范
好了,原理有了一定的了解之后,接下来就是如何防范了。
问题的源头在于js代码的注入,我们可以想个办法,不让js生效不就行了?
大家要注意两头的防范:
1)输入。
在提交表单时,前端最好将文本内容转为html实体编码,也就是过滤掉**
2)输出。
在显示文本内容时,最好也要做一次html实体编码转换后再显示,防止**
三、手段
这里给大家介绍一种简单的处理办法。
1、如果您是用的vue、react或node。
安装:
$ npm install xss --save
使用:
xss攻击图7
2、也可以直接在页面引用。
引入文件:
https://raw.github.com/leizongmin/js-xss/master/dist/xss.js
使用:
xss攻击图8
四、实现原理
实现的原理也很简单,就是过滤掉不该有的标签即可,我们可以这样来写:
xss攻击图9
大家可以顺着这个思路,自己动手写一个这样的函数。
2、如何防止CSRF攻击?
防御措施
检查Referer字段
HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于www.examplebank.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于www.examplebank.com之下,这时候服务器就能识别出恶意的访问。
这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。
添加校验token
由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再运行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。
3、浏览器为什么要阻止跨域请求?
防止CSRF攻击,比如说有两个网站 A和B。
你是A网站的管理员,你在A网站有一个权限是删除用户,比如说这个过程只需用你的身份登陆并且POST数据到http://a.com/delUser,就可以实现删除操作。
好现在说B网站,B网站被攻击了,别人种下了恶意代码,你点开的时候就会模拟跨域请求,如果是针对你,那么就可以模拟对A站的跨域请求,恰好这个时候你已经在A站登陆了。那么攻击者在B站内通过脚本,模拟一个用户删除操作是很简单的。
面对这种问题,有从浏览器解决,但个人认为最好是从网站端解决,检测每次POST过来数据时热refer,添加accesstoken等都是好方法。