JSX
什么是JSX
Javascript的语法拓展,既不是HTML也不是字符串,具有Javascript所有功能。JSX可以生成React元素。
为什么使用JSX
React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合。即在JSX中,需要包含如下内容:绑定事件的处理,订阅状态变化及更新UI,准备好UI展示的数据。
JSX表示对象
Babel中会把JSX转译成React.createElement()函数进行使用:
const element = <div>
<h1 className='jsx'>
Hello world!!
</h1>
</div>
// babel转译后
const element = React.createElement(
'h1',
{className: 'jsx'},
'Hello world'
)
// 等效于
const element = {
type: 'h1',
props: {
className: 'jsx',
children: 'Hello, world!'
}
};
JSX 可以防止XSS攻击
React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串:
<img src="empty.png" onerror="alert(xss)" />
// 转义后
<img src="empty.png" onerror=$quot;alert(%#x27;xss%#x27;)">
在熟悉JSX后,如果我们尝试使用特殊构造的JSX转义对象由服务端进行XSS注入攻击,也是无法成功的:
const jsonStr = `{
"ref": null,
"type": "body",
"props": {
"dangerouslySetInnerHtml": {
"_html": "<img src=\"empty.png\" onerror=\"alert('xss')\" />"
}
}
}`
const parseData = JSON.parse(jsonStr)
render() {
return <span> {parseData} </span>
}
上述代码执行会报错:
Uncaught (in promise) Error: Objects are not valid as a React Child...
在JSX转义的过程中,会在属性中加入使用Symbol.for创建的唯一$$typeof标识,一旦打算使用xss攻击生成React元素时,ReactElement在运行中发现不存在$$typeof或者值不同时,就会报错不继续执行。$$typeof是个symbol属性,进行JSON.parse()值会丢失