【问题标题】:Render html saved from draft-js渲染从 Draft-js 保存的 html
【发布时间】:2018-08-16 21:35:37
【问题描述】:

我正在学习 React:完全是新手。

如果我直接从 draft.js 将 HTML 保存在 DB 中(或者它的变体总是基于它),然后在我的 React SPA 的视图页面中,我通过我的 API 从 DB 检索 HTML:

问题:

【问题讨论】:

    标签: javascript reactjs react-native draftjs draft-js-plugins


    【解决方案1】:

    Draft-JS 不允许您直接从当前的EditorState 生成 HTML,这是一件好事。由于您不是在处理“原始 HTML”,因此您不必处理 XSS 攻击,因为如果有人在编辑器中插入脚本,草稿编辑器的内部状态不会改变。

    Draft JS 允许您导出当前编辑器状态,以便您可以轻松存储它。可以使用

    import {convertToRaw} from 'draft-js';
    

    在你的 onChange 处理程序中你可以简单地做

    const editorJSON = JSON.stringify(convertToRaw(editorState.getCurrentContent()));
    

    您可以随意存储此 JSON 以供将来使用。

    现在渲染这个你有两个选择:

    1. 从存储的 EditorState 生成 HTML。

      这可以使用像 https://www.npmjs.com/package/draft-js-export-html 这样的库来完成。您可能希望避免这种情况,因为我认为下一个选项更好。

    2. 将此 EditorState 用作只读 DraftJS 编辑器的默认值

      你将需要 DraftJS 库中的 convertFromRaw,然后你会像这样制作一个不错的 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 处理。

    【讨论】:

    【解决方案2】:

    不要相信用户!

    您首先应该注意的是“不要相信您的用户”。

    如果您的“HTML”由您的服务器呈现并且用户无法修改,则完全可以。 因为你渲染/保存的 HTML 是完全安全的并且由你自己管理,如果它被确定为“安全”的 HTML,你是否将它(html)放入 DOM 根本不是问题。

    但问题是,大多数 WYSIWYG 编辑器——比如draft.js——制作的“HTML”文件不是文本。我想你的担心也来自这里。

    是的,这很危险。我们能做的不是直接渲染 HTML,而是“选择性”渲染 HTML。

    危险标签:&lt;script&gt;&lt;img&gt;&lt;link&gt;

    您可以删除这些标签,但当您决定允许哪些标签时会更安全,如下所示:

    安全标签:&lt;H1&gt; - &lt;H6&gt;/span/div/p/olulli/table...

    并且您应该删除那些 HTML 元素的属性,例如 onclick="" 等。

    因为它也可能被用户滥用。

    结论:

    那么当我们使用所见即所得的编辑器时,我们可以做什么呢?

    有2大策略:

    1. 在对数据库安全时生成“安全”HTML。
    2. 在将其放入 DOM 之前生成“安全”HTML。 (3. 在将 html 发送到客户端之前生成“安全”HTML,但您的情况并非如此!)

    如果您想确保数据库的文本完全安全,请选择第一个。

    第一个必须在您的服务器中处理(不是浏览器/客户端!),您可以使用许多解决方案,例如 python 中的BeautifulSoup,或 nodejs 中的sanitize-html

    如果您的 Web 应用程序很复杂,并且您的服务的大部分业务逻辑都在前端运行,请选择第二个。

    第二个是在将 HTML 挂载到 DOM 之前使用 HTML 转义包。仍然sanitize-html 可以是很好的解决方案。 (当然还有更多很棒的解决方案!) 您可以决定 HTML 中的哪些标签/属性/值。


    链接

    https://github.com/punkave/sanitize-html

    【讨论】:

    • 好的。非常感谢。并在反应中渲染 html?那些包裹呢?
    • @JohnSam 嗯,你能告诉我更具体的吗?我无法理解你的评论;)
    • 在我的问题中,我问:“dangerouslySetInnerHTML?或者可能是其中之一(你有什么建议?)?”
    • 当您生成过滤(安全)html 时,您可以安全地使用 innerHTML ;)
    • 在安装组件之前让你的 html 安全。
    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2016-11-13
    • 2019-04-17
    • 1970-01-01
    • 2017-06-25
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多