React.js将HTML字符串转换为JSX


212

我在处理Facebook的ReactJS时遇到问题。每当我执行ajax并想要显示html数据时,ReactJS都会将其显示为文本。(见下图)

ReactJS渲染字符串

通过jquery Ajax的成功回调函数显示数据。

$.ajax({
   url: url here,
   dataType: "json",
   success: function(data) {
      this.setState({
           action: data.action
      })
   }.bind(this)
});

在此处输入图片说明

有没有简单的方法可以将其转换为html?我应该如何使用ReactJS?

Answers:


405

默认情况下,React会转义HTML以防止XSS(跨站点脚本)。如果您确实要呈现HTML,则可以使用dangerouslySetInnerHTML属性:

<td dangerouslySetInnerHTML={{__html: this.state.actions}} />

React强制使用这种故意繁琐的语法,这样您就不会意外地将文本呈现为HTML并引入XSS错误。


4
该语法显示在首页和教程中,但我只是意识到它没有在其他任何地方进行记录,因此我提交了#413进行修复。
2013年

正确!我已经解决了这个已经使用dangerouslySetInnerHTML但由于虽然:)
彼得Wateber

如果要从外部API获取信息,则值得安全地使用npm包中的sanitize函数对内容进行清理dompurify
巴里·迈克尔·道尔

77

现在有更安全的方法可以完成此操作。该文档已更新,使用这些方法。

其他方法

  1. 最简单 -使用Unicode,将文件另存为UTF-8并将其设置charset为UTF-8。

    <div>{'First · Second'}</div>

  2. 更安全 -在Javascript字符串中为实体使用Unicode数字。

    <div>{'First \u00b7 Second'}</div>

    要么

    <div>{'First ' + String.fromCharCode(183) + ' Second'}</div>

  3. 或包含字符串和JSX元素的混合数组。

    <div>{['First ', <span>&middot;</span>, ' Second']}</div>

  4. 不得已 -使用插入原始HTML dangerouslySetInnerHTML

    <div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />


15
我已经准备好文档,但是关于一个长HTML字符串(例如,所见即所得编辑器中的HTML字符串)?我看不到如何使用第一种
第二种

4
我同意@eric。方法1-3用于将已转义的内容存储在某个地方(例如DB)有什么用?还要注意,方法4(唯一的方法)意味着您不能添加子节点。
dvdplm 2015年

14
对。这些带有硬编码的“动态”内容的示例没有多大意义。
regularmike

这是我的innerHTML-“正在显示admins-\ u00326b \ u003e13 \ u003c / b \ u003e总共\ u003cb \ u003e13 \ u003c / b \ u003e”-这是正在呈现的内容-“显示总共<b> 13 </ b>的管理员<b> 1&nbsp;-&nbsp; 10 </ b>”。当我尝试危险地使用SetInnerHTML时,一切中断。
vipin8169 '16

36

我建议使用交织产生的milesj。它是一个了不起的库,它利用许多巧妙的技术来解析和安全地将HTML插入DOM。

Interweave是一个React库,用于安全地呈现HTML,过滤器属性,使用匹配器自动换行文本,呈现表情符号字符等等。

  • Interweave是一个强大的React库,可以:
    • 安全地呈现HTML,而无需使用dragonallySetInnerHTML。
    • 安全地剥离HTML标记。
    • 自动XSS和注入保护。
    • 使用过滤器清除HTML属性。
    • 使用匹配器内插组件。
    • 自动链接URL,IP,电子邮件和主题标签。
    • 渲染表情符号和表情符号字符。
    • 以及更多!

用法示例:

import React from 'react';
import { Markup } from 'interweave';

const articleContent = "<p><b>Lorem ipsum dolor laboriosam.</b> </p><p>Facere debitis impedit doloremque eveniet eligendi reiciendis <u>ratione obcaecati repellendus</u> culpa? Blanditiis enim cum tenetur non rem, atque, earum quis, reprehenderit accusantium iure quas beatae.</p><p>Lorem ipsum dolor sit amet <a href='#testLink'>this is a link, click me</a> Sunt ducimus corrupti? Eveniet velit numquam deleniti, delectus  <ol><li>reiciendis ratione obcaecati</li><li>repellendus culpa? Blanditiis enim</li><li>cum tenetur non rem, atque, earum quis,</li></ol>reprehenderit accusantium iure quas beatae.</p>"

<Markup content={articleContent} /> // this will take the articleContent string and convert it to HTML markup. See: https://milesj.gitbook.io/interweave


//to install package using npm, execute the command
npm install interweave

您能提供一个用法示例吗?
El Anonimo '18年

1
@ElAnonimo我添加了一个用法示例。希望这会使事情变得更加清晰。
阿曼·尼施

1
感谢一百万,交织正是我所需要的。干杯。
尼古拉斯·汉密尔顿

1
此文档没有帮助。我也尝试了几行html,并且页面上充满了错误消息。有人有示例或任何带有文档的资源吗?
塔伦·科拉


6

我发现这个js小提琴。这是这样的

function unescapeHTML(html) {
    var escapeEl = document.createElement('textarea');
    escapeEl.innerHTML = html;
    return escapeEl.textContent;
}

<textarea className="form-control redactor"
                          rows="5" cols="9"
                          defaultValue={unescapeHTML(this.props.destination.description)}
                          name='description'></textarea>

jsfiddle链接


不幸的是,文档无法在服务器渲染上工作。
劳伦·范温克尔

如果您愿意的话,它可能import JSDOM from 'jsdom'; global.window = new JSDOM('', { url: 'http://localhost' }); global.document = global.window.document;会给您带来好运
Coty Embry



1

对于仍在尝试的人,npm install react-html-parser

当我安装它时,它每周下载123628。

import ReactHtmlParser from 'react-html-parser'

<div>{ReactHtmlParser(htmlString)}</div>

0

如果您想在React中呈现原始HTML,可以使用以下内容

<div dangerouslySetInnerHTML={{__html: `html-raw-goes-here`}} />

示例-渲染

测试是美好的一天

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.