我正在学习React:完全是新手。
如果我直接从draft.js(或基于它的变体)保存HTML到数据库中,然后在我的React SPA的视图页面中通过我的API检索HTML:
问题:
如何呈现该HTML?
使用dangerouslySetInnerHTML?还是您建议的以下其中一个(哪个)?
我读到了“消毒”、“安全HTML”等词语。但是,有什么库呢?
我需要在将其保存到DB中或渲染时后,对来自draft-js的html进行安全化处理吗?
我正在学习React:完全是新手。
如果我直接从draft.js(或基于它的变体)保存HTML到数据库中,然后在我的React SPA的视图页面中通过我的API检索HTML:
问题:
如何呈现该HTML?
使用dangerouslySetInnerHTML?还是您建议的以下其中一个(哪个)?
我读到了“消毒”、“安全HTML”等词语。但是,有什么库呢?
我需要在将其保存到DB中或渲染时后,对来自draft-js的html进行安全化处理吗?
Draft-JS不允许您直接从当前EditorState
生成HTML,这是一件好事。因为您不处理“原始HTML”,所以无需处理XSS攻击,因为如果有人在编辑器中插入脚本,则Draft Editor的内部状态不会被更改。
Draft JS允许您导出当前的Editor状态,以便轻松存储。可以使用下面的方法完成:
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编辑器组件的默认值。
您将需要使用DraftJS库中的convertFromRaw
,然后创建一个漂亮的无状态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,无论是否将其放入 DOM 中都不是问题。
但问题是,大多数所见即所得(WYSIWYG)编辑器 - 如 draft.js
- 生成的是“HTML”文件而不是文本。我认为你的担忧也来自于此。
是的,这很危险。我们能做的就是不直接渲染 HTML,而是进行“选择性” HTML 渲染。
危险的标签: <script>
、<img>
、<link>
等。
你可以删除这些标签,但当你决定允许哪些标签时,它会更加安全,例如:
安全标签:<H1> - <H6>
/ span
/ div
/ p
/ ol
ul
li
/ table
...
你应该删除这些 HTML 元素的属性,例如:onclick=""
等。
因为它也可能被用户滥用。
那么当我们使用 WYSIWYG 编辑器时该怎么办?
有两个大策略:
如果你想确保数据库中的文本是完全安全的,请选择第一种方法。
第一种方法必须在服务器上处理(而不是浏览器/客户端!),你可以使用许多解决方案,如 Python 中的 BeautifulSoup
或 Node.js 中的 sanitize-html
。
如果你的 Web 应用程序很复杂,并且大部分服务的业务逻辑在前端运行,则选择第二种方法。
第二种方法是在将 HTML 挂载到 DOM 前使用 HTML 转义包。仍然可以使用 sanitize-html
(当然还有更好的解决方案!)你可以决定 HTML 中的哪些标签/属性/值。
对我来说,2022年它的工作方式有些不同
import { convertFromRaw, Editor, EditorState } from 'draft-js';
function Comments() {
const itemText= EditorState.createWithContent(convertFromRaw(JSON.parse(item.content)));
return <Editor editorState={itemText} readOnly={true} />
}
并且它被保存到数据库中就是那样的
JSON.stringify(convertToRaw(editorState.getCurrentContent()))
区别在于如果没有EditorState,对我来说它就无法工作,我相信我不是唯一一个这样的人
getCurrentContent()
:https://draftjs.org/docs/api-reference-editor-state#getcurrentcontent - Neurotransmitter