Javascript 使用 reactjs 渲染原始 html
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27934238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rendering raw html with reactjs
提问by vinhboy
So is this the only way to render raw html with reactjs?
那么这是使用 reactjs 呈现原始 html 的唯一方法吗?
// http://facebook.github.io/react/docs/tutorial.html
// tutorial7.js
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
);
}
});
I know there are some cool ways to markup stuff with JSX, but I am mainly interested in being able to render raw html (with all the classes, inline styles, etc..). Something complicated like this:
我知道有一些很酷的方法可以用 JSX 来标记东西,但我主要对能够呈现原始 html(带有所有类、内联样式等)感兴趣。像这样复杂的东西:
<!-- http://getbootstrap.com/components/#dropdowns-example -->
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
I would not want to have to rewrite all of that in JSX.
我不想在 JSX 中重写所有这些。
Maybe I am thinking about this all wrong. Please correct me.
也许我在想这一切都是错误的。请纠正我。
采纳答案by Mike Nikles
You could leverage the html-to-reactnpm module.
您可以利用html-to-reactnpm 模块。
Note: I'm the author of the module and just published it a few hours ago. Please feel free to report any bugs or usability issues.
注意:我是该模块的作者,几个小时前刚刚发布。请随时报告任何错误或可用性问题。
回答by Brett DeWoody
There are now safer methods to render HTML. I covered this in a previous answer here. You have 4 options, the last uses dangerouslySetInnerHTML.
现在有更安全的方法来呈现 HTML。我在之前的回答中介绍了这一点。您有 4 个选项,最后一个使用dangerouslySetInnerHTML.
Methods for rendering HTML
呈现 HTML 的方法
Easiest- Use Unicode, save the file as UTF-8 and set the
charsetto UTF-8.<div>{'First · Second'}</div>Safer- Use the Unicode number for the entity inside a Javascript string.
<div>{'First \u00b7 Second'}</div>or
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>Or a mixed array with strings and JSX elements.
<div>{['First ', <span>·</span>, ' Second']}</div>Last Resort- Insert raw HTML using
dangerouslySetInnerHTML.<div dangerouslySetInnerHTML={{__html: 'First · Second'}} />
最简单- 使用 Unicode,将文件另存为 UTF-8 并将 设置
charset为 UTF-8。<div>{'First · Second'}</div>更安全- 对 Javascript 字符串中的实体使用 Unicode 编号。
<div>{'First \u00b7 Second'}</div>或者
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>或者带有字符串和 JSX 元素的混合数组。
<div>{['First ', <span>·</span>, ' Second']}</div>最后的手段- 使用
dangerouslySetInnerHTML.<div dangerouslySetInnerHTML={{__html: 'First · Second'}} />
回答by Cory Robinson
I have used this in quick and dirty situations:
我在快速和肮脏的情况下使用过这个:
// react render method:
render() {
return (
<div>
{ this.props.textOrHtml.indexOf('</') !== -1
? (
<div dangerouslySetInnerHTML={{__html: this.props.textOrHtml.replace(/(<? *script)/gi, 'illegalscript')}} >
</div>
)
: this.props.textOrHtml
}
</div>
)
}
回答by Netsi1964
I have tried this pure component:
我试过这个纯组件:
const RawHTML = ({children, className = ""}) =>
<div className={className}
dangerouslySetInnerHTML={{ __html: children.replace(/\n/g, '<br />')}} />
Features
特征
- Takes
classNameprop (easier to style it) - Replaces
\nto<br />(you often want to do that) - Place content as childrenwhen using the component like:
<RawHTML>{myHTML}</RawHTML>
- 需要
className道具(更容易设计) - 替换
\n为<br />(你经常想这样做) - 使用组件时将内容作为子项放置,例如:
<RawHTML>{myHTML}</RawHTML>
I have placed the component in a Gist at Github: RawHTML: ReactJS pure component to render HTML
我已将该组件放在 Github 的 Gist 中:RawHTML: ReactJS pure component to render HTML
回答by Jozcar
export class ModalBody extends Component{
rawMarkup(){
var rawMarkup = this.props.content
return { __html: rawMarkup };
}
render(){
return(
<div className="modal-body">
<span dangerouslySetInnerHTML={this.rawMarkup()} />
</div>
)
}
}
回答by Yuci
dangerouslySetInnerHTMLis React's replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack.
risklySetInnerHTML是 React 在浏览器 DOM 中使用 innerHTML 的替代品。一般来说,从代码中设置 HTML 是有风险的,因为很容易在不经意间将用户暴露给跨站点脚本 (XSS) 攻击。
It is better/safer to sanitise your raw HTML (using e.g., DOMPurify) before injecting it into the DOM via dangerouslySetInnerHTML.
在将原始 HTML 通过dangerouslySetInnerHTML.
DOMPurify- a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks.
DOMPurify- 用于 HTML、MathML 和 SVG 的仅 DOM、超快、超容忍 XSS 清理程序。DOMPurify 使用安全的默认设置,但提供了许多可配置性和挂钩。
Example:
示例:
import React from 'react'
import createDOMPurify from 'dompurify'
import { JSDOM } from 'jsdom'
const window = (new JSDOM('')).window
const DOMPurify = createDOMPurify(window)
const rawHTML = `
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
`
const YourComponent = () => (
<div>
{ <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(rawHTML) }} /> }
</div>
)
export default YourComponent
回答by ecairol
I used this library called Parser. It worked for what I needed.
我使用了这个名为 Parser 的库。它适用于我需要的东西。
import React, { Component } from 'react';
import Parser from 'html-react-parser';
class MyComponent extends Component {
render() {
<div>{Parser(this.state.message)}</div>
}
};
回答by Breno Ferreira
dangerouslySetInnerHTMLshould not be used unless absolutely necessary. According to the docs, "This is mainly for cooperating with DOM string manipulation libraries". When you use it, you're giving up the benefit of React's DOM management.
dangerouslySetInnerHTML除非绝对必要,否则不应使用。根据文档,“这主要是为了与 DOM 字符串操作库合作”。当你使用它时,你就放弃了 React DOM 管理的好处。
In your case, it is pretty straightforward to convert to valid JSX syntax; just change classattributes to className. Or, as mentioned in the comments above, you can use the ReactBootstraplibrary which encapsulates Bootstrap elements into React components.
在您的情况下,转换为有效的 JSX 语法非常简单;只需将class属性更改为className. 或者,如上面的评论中所述,您可以使用ReactBootstrap库,它将 Bootstrap 元素封装到 React 组件中。
回答by Christiaan Westerbeek
Here's a little less opinionated version of the RawHTML function posted before. It lets you:
这是之前发布的 RawHTML 函数的一个不那么固执己见的版本。它让你:
- configure the tag
- optionally replace newlines to
<br />'s - pass extra props that RawHTML will pass to the created element
- supply an empty string (
RawHTML></RawHTML>)
- 配置标签
- 可选地将换行符替换为
<br />'s - 传递 RawHTML 将传递给创建的元素的额外道具
- 提供一个空字符串 (
RawHTML></RawHTML>)
Here's the component:
这是组件:
const RawHTML = ({ children, tag = 'div', nl2br = true, ...rest }) =>
React.createElement(tag, {
dangerouslySetInnerHTML: {
__html: nl2br
? children && children.replace(/\n/g, '<br />')
: children,
},
...rest,
});
RawHTML.propTypes = {
children: PropTypes.string,
nl2br: PropTypes.bool,
tag: PropTypes.string,
};
Usage:
用法:
<RawHTML>{'First · Second'}</RawHTML>
<RawHTML tag="h2">{'First · Second'}</RawHTML>
<RawHTML tag="h2" className="test">{'First · Second'}</RawHTML>
<RawHTML>{'first line\nsecond line'}</RawHTML>
<RawHTML nl2br={false}>{'first line\nsecond line'}</RawHTML>
<RawHTML></RawHTML>
Output:
输出:
<div>First · Second</div>
<h2>First · Second</h2>
<h2 class="test">First · Second</h2>
<div>first line<br>second line</div>
<div>first line
second line</div>
<div></div>
It will break on:
它将打破:
<RawHTML><h1>First · Second</h1></RawHTML>
回答by Adam Lane
I needed to use a link with onLoad attribute in my head where div is not allowed so this caused me significant pain. My current workaround is to close the original script tag, do what I need to do, then open script tag (to be closed by the original). Hope this might help someone who has absolutely no other choice:
我需要在我的头脑中使用带有 onLoad 属性的链接,其中 div 是不允许的,所以这给我带来了很大的痛苦。我目前的解决方法是关闭原始脚本标签,做我需要做的事情,然后打开脚本标签(被原始标签关闭)。希望这可以帮助那些绝对没有其他选择的人:
<script dangerouslySetInnerHTML={{ __html: `</script>
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans" as="style" onLoad="this.onload=null;this.rel='stylesheet'" crossOrigin="anonymous"/>
<script>`,}}/>

