从draft-js保存的HTML呈现

7

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

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

问题:

3个回答

10

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存储以备将来使用。

现在有两种选项来渲染它:

  1. 从存储的EditorState生成HTML。

    这可以使用诸如https://www.npmjs.com/package/draft-js-export-html之类的库完成。 我认为您可能希望避免这样做,因为下一个选项要好得多。

  2. 将此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的情况下呈现内容。


1
获取状态内容的函数现在是 getCurrentContent():https://draftjs.org/docs/api-reference-editor-state#getcurrentcontent - Neurotransmitter
从服务器端渲染时加载所有这些脚本会影响您的响应性能。 - undefined

4

不要相信用户!

首先,你应该关心的是“不要相信你的用户”。

如果你的“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 编辑器时该怎么办?

有两个大策略:

  1. 在安全时将“安全” HTML 生成到数据库中。
  2. 在将其放入 DOM 之前生成“安全” HTML。 (3. 在发送 HTML 到客户端之前生成“安全” HTML,但这不是你的情况!)

如果你想确保数据库中的文本是完全安全的,请选择第一种方法。

第一种方法必须在服务器上处理(而不是浏览器/客户端!),你可以使用许多解决方案,如 Python 中的 BeautifulSoup 或 Node.js 中的 sanitize-html

如果你的 Web 应用程序很复杂,并且大部分服务的业务逻辑在前端运行,则选择第二种方法。

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


链接

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


好的。非常感谢。那么在React中呈现HTML呢?那些包怎么样? - user4412054
@JohnSam 嗯,你能具体说得更清楚一些吗?我没听懂你的评论 ;) - Beomi
在我的问题中,我问道:“dangerouslySetInnerHTML?还是这些中的一个(你建议哪个)?” - user4412054
当你生成经过过滤的(安全的)HTML时,使用innerHTML是安全的。 - Beomi
在挂载组件之前,确保你的 HTML 是安全的。 - Beomi

1

对我来说,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,对我来说它就无法工作,我相信我不是唯一一个这样的人


1
我也一样,2023年对我来说可以。谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接