[英]Render html saved from draft-js
我正在学习 React:完全是新手。
如果我将 HTML 直接从 draft.js(或者它的变体总是基于它)保存在数据库中,然后在我的 React SPA 的视图页面中,我通过我的 API 从数据库中检索 HTML:
问题:
我如何呈现 HTML?
危险地设置内部HTML? 或者其中之一(你有什么建议?)?
我读到诸如“清理”、“保护 HTML”之类的词。 但是,怎么会有图书馆呢?
当我将 html 保存在数据库中时或之后,当我渲染它时,我需要从 draft-js 中保护它吗?
Draft-JS不允许您直接从当前的EditorState
生成HTML,这是一件好事。 由于您没有处理“原始HTML”,因此无需处理XSS攻击,因为如果有人在编辑器中插入脚本,则草稿编辑器内部状态不会被更改。
Draft JS允许您导出当前的Editor状态,以便您可以轻松存储它。 它可以使用
import {convertToRaw} from 'draft-js';
在你的onChange
Handler中你可以做到
const editorJSON = JSON.stringify(convertToRaw(EditorState.getContents()));
您可以根据需要存储此JSON以备将来使用。
现在渲染这个你有两个选择:
从存储的EditorState生成HTML。
这可以使用https://www.npmjs.com/package/draft-js-export-html等库来完成。 您可能希望避免这种情况,因为我认为下一个选项更好。
使用此EditorState作为只读DraftJS编辑器组件的默认值 。
你将需要从DraftJS库convertFromRaw
convertFromRaw然后你就像这样制作一个Nice StateLess React Component
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都不是问题。
但问题是,大多数WYSIWYG编辑器 - 比如draft.js
- 使“HTML”文件不是TEXT。 我想你的担心也来自这里。
是的,这很危险。 我们能做的不是直接渲染HTML而是“选择性”HTML渲染。
危险标签: <script>
, <img>
, <link>
等
你可以删除那些标签但是当你决定允许哪些标签时它会更安全,如下所示:
安全标签: <H1> - <H6>
/ span
/ div
/ p
/ ol
ul
li
/ table
...
你应该删除那些HTML元素的属性,比如, onclick=""
等。
因为它也可能被用户滥用。
那么当我们使用WYSIWYG编辑器时我们能做些什么呢?
有两大策略:
如果您想确保数据库的文本完全安全,请选择第一个。
第一个必须在您的服务器(而不是浏览器/客户端!)中处理,您可以使用许多解决方案,如python中的BeautifulSoup
,或nodejs中的sanitize-html
。
如果您的网络应用程序很复杂,并且大多数服务的业务逻辑都在前端运行,请选择第二个。
第二个是在将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 的我来说它不起作用,我相信我并不孤单
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.