react dangerouslysetinnerhtml javascript reactjs

javascript - dangerouslysetinnerhtml - react native



Representación de HTML sin formato con reactjs (10)

Ahora hay métodos más seguros para representar HTML. Cubrí esto en una respuesta anterior here . Tienes 4 opciones, la última usa dangerouslySetInnerHTML .

Métodos para renderizar HTML

  1. Más fácil : use Unicode, guarde el archivo como UTF-8 y configure el juego de charset en UTF-8.

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

  2. Más seguro : use el número Unicode para la entidad dentro de una cadena Javascript.

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

    o

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

  3. O una matriz mixta con cadenas y elementos JSX.

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

  4. Último recurso : inserte HTML sin formato con dangerouslySetInnerHTML .

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

Entonces, ¿es esta la única forma de procesar html sin procesar con reactjs?

// 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> ); } });

Sé que hay algunas formas geniales de marcar cosas con JSX, pero estoy interesado principalmente en poder procesar html sin formato (con todas las clases, estilos en línea, etc.). Algo complicado como este:

<!-- 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>

No me gustaría tener que volver a escribir todo eso en JSX.

Tal vez estoy pensando en todo esto mal. Por favor corrigeme.


Aquí hay una versión menos obstinada de la función RawHTML publicada anteriormente. Te permite:

  • configurar la etiqueta
  • opcionalmente reemplace las nuevas líneas a las <br />
  • pasar accesorios adicionales que RawHTML pasará al elemento creado
  • proporcionar una cadena vacía ( RawHTML></RawHTML> )

Aquí está el componente:

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, };

Uso:

<RawHTML>{''First &middot; Second''}</RawHTML> <RawHTML tag="h2">{''First &middot; Second''}</RawHTML> <RawHTML tag="h2" className="test">{''First &middot; Second''}</RawHTML> <RawHTML>{''first line/nsecond line''}</RawHTML> <RawHTML nl2br={false}>{''first line/nsecond line''}</RawHTML> <RawHTML></RawHTML>

Salida:

<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>

Se romperá en:

<RawHTML><h1>First &middot; Second</h1></RawHTML>


He probado este componente puro:

const RawHTML = ({children, className = ""}) => <div className={className} dangerouslySetInnerHTML={{ __html: children.replace(//n/g, ''<br />'')}} />

Caracteristicas

  • Toma className prop (más fácil de peinar)
  • Reemplaza /n por <br /> (a menudo quieres hacer eso)
  • Coloque contenido como hijos cuando use el componente como:
  • <RawHTML>{myHTML}</RawHTML>

He colocado el componente en un Gist en Github: RawHTML: componente puro ReactJS para renderizar HTML


He usado esto en situaciones rápidas y sucias:

// 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> ) }


Necesitaba usar un enlace con el atributo onLoad en mi cabeza donde div no está permitido, por lo que esto me causó un dolor significativo. Mi solución actual es cerrar la etiqueta del script original, hacer lo que necesito hacer y luego abrir la etiqueta del script (para que el original la cierre). Espero que esto pueda ayudar a alguien que no tiene otra opción:

<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>`,}}/>


Puede aprovechar el módulo html-to-react npm.

Nota: Soy el autor del módulo y lo publiqué hace unas horas. No dude en informar cualquier error o problema de usabilidad.


Usé esta biblioteca llamada Parser . Funcionó para lo que necesitaba.

import React, { Component } from ''react''; import Parser from ''html-react-parser''; class MyComponent extends Component { render() { <div>{Parser(this.state.message)}</div> } };


dangerouslySetInnerHTML es el reemplazo de React para usar innerHTML en el DOM del navegador. En general, establecer HTML a partir del código es arriesgado porque es fácil exponer a sus usuarios sin darse cuenta a un ataque de secuencias de comandos entre sitios (XSS).

Es mejor / más seguro desinfectar su HTML sin formato (usando, por ejemplo, DOMPurify) antes de inyectarlo en el DOM a través de dangerouslySetInnerHTML .

DOMPurify : un desinfectante XSS súper rápido, súper rápido y solo DOM para HTML, MathML y ​​SVG. DOMPurify funciona con un valor predeterminado seguro, pero ofrece mucha capacidad de configuración y ganchos.

Ejemplo :

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


dangerouslySetInnerHTML no debe usarse a menos que sea absolutamente necesario. Según los documentos, "Esto es principalmente para cooperar con las bibliotecas de manipulación de cadenas DOM" . Cuando lo usas, estás renunciando al beneficio de la administración DOM de React.

En su caso, es bastante sencillo convertir a una sintaxis JSX válida; simplemente cambie class atributos de class a className . O, como se menciona en los comentarios anteriores, puede usar la biblioteca ReactBootstrap que encapsula elementos Bootstrap en componentes React.


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> ) } }