我正在学习 React:完全是新手。
如果我直接从 draft.js 将 HTML 保存在 DB 中(或者它的变体总是基于它),然后在我的 React SPA 的视图页面中,我通过我的 API 从 DB 中检索 HTML:
问题:
如何呈现该 HTML?
危险地设置InnerHTML?或者也许其中之一(你有什么建议?)?
我读过诸如“清理”、“保护 HTML”之类的词。但是,有图书馆吗?
当我将它保存在 DB 中或之后,当我渲染它时,我需要从 Draft-js 中保护 html?
我正在学习 React:完全是新手。
如果我直接从 draft.js 将 HTML 保存在 DB 中(或者它的变体总是基于它),然后在我的 React SPA 的视图页面中,我通过我的 API 从 DB 中检索 HTML:
问题:
如何呈现该 HTML?
危险地设置InnerHTML?或者也许其中之一(你有什么建议?)?
我读过诸如“清理”、“保护 HTML”之类的词。但是,有图书馆吗?
当我将它保存在 DB 中或之后,当我渲染它时,我需要从 Draft-js 中保护 html?
Draft-JS 不允许您直接从当前生成 HTML,EditorState
这是一件好事。由于您不是在处理“原始 HTML”,因此您不必处理 XSS 攻击,因为如果有人在编辑器中插入脚本,草稿编辑器的内部状态不会改变。
Draft JS 允许您导出当前的编辑器状态,以便您可以轻松存储它。可以使用
import {convertToRaw} from 'draft-js';
在你的onChange
处理程序中你可以简单地做
const editorJSON = JSON.stringify(convertToRaw(editorState.getCurrentContent()));
您可以根据需要存储此 JSON 以供将来使用。
现在渲染这个你有两个选择:
从存储的 EditorState 生成 HTML。
这可以使用诸如https://www.npmjs.com/package/draft-js-export-html之类的库来完成。您可能希望避免这种情况,因为我认为下一个选项更好。
将此 EditorState 用作只读 DraftJS 编辑器组件的默认值。
您将需要convertFromRaw
DraftJS 库,然后像这样制作一个不错的 StateLess React 组件
import React from 'react';
import {Editor, ConvertFromRaw} from 'draft-js';
const ReadOnlyEditor = (props) => {
const storedState = ConvertFromRaw(JSON.parse(props.storedState));
return (
<div className="readonly-editor">
<Editor editorState={storedState} readOnly={true} />
</div>
);
}
现在您可以简单地使用它来显示您的内容。您还可以传递您的装饰器和自定义映射函数,通常是您传递给普通编辑器的所有内容,并且可以呈现内容而不会丢失样式和繁琐的 HTML 处理。
你应该关心的第一件事是“不要相信你的用户”。
如果您的“HTML”由您的服务器呈现并且用户无法修改,那完全可以。因为您渲染/保存的 HTML 是完全安全的并且由您自己管理,并且如果它被确定为“安全”HTML,那么您是否将它(html)放入 DOM 根本不是问题。
但问题是,大多数所见即所得的编辑器——比如draft.js
——制作“HTML”文件而不是文本。我想你的担心也来自这里。
是的,这很危险。我们能做的不是直接渲染 HTML,而是“选择性”渲染 HTML。
危险标签:<script>
、、、<img>
等<link>
。
您可以删除这些标签,但当您决定允许哪些标签时会更安全,如下所示:
安全标签:<H1> - <H6>
/ span
/ div
/ p
/ ol
ul
li
/ table
...
并且您应该删除那些 HTML 元素的属性,例如,onclick=""
等。
因为它也可能被用户滥用。
那么当我们使用 WYSIWYG 编辑器时,我们可以做什么呢?
有2个大策略:
如果您想确保数据库的文本完全安全,请选择第一个。
第一个必须在您的服务器(不是浏览器/客户端!)中处理,您可以使用许多解决方案BeautifulSoup
,例如在 python 或sanitize-html
nodejs 中。
如果您的 web 应用程序很复杂,并且您的服务的大部分业务逻辑都在前端运行,请选择第二个。
第二个是在将 HTML 挂载到 DOM 之前使用 HTML 转义包。仍然sanitize-html
可以是很好的解决方案。(当然还有更棒的解决方案!)您可以决定 HTML 中的哪些标签/属性/值。