Как визуализировать тег скрипта внутри JSX, не создавая его вручную - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть HTML документы, которые я получаю из своего бэкэнда. Эти документы состоят из 2 видов тегов, и я хочу, чтобы они отображались динамически. Это мой исходный код

const Content = ({ slug }) => {
  const [data, setData] = useState()
  useScript("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js");

  useEffect(() => {

    api.posts.read({ slug: slug }, { formats: ["html", "plaintext"] }).then((resp) => {
      setData(resp)
    })
  }, [slug])

  if (data) {
    return (
      <>
        <SEO
          title={data.title}
          description={data.meta_description}
          canonical_url={data.canonical_url}/>
          <section className={'content'}>
            <h4 className={'content-title'}>{data.title}</h4>
            <div dangerouslySetInnerHTML={{ __html: data.html }}/>
          </section>
      </>
      )
  }
  return <Section>
    <CircularProgress style={{color: '#004D80'}}/>
    <p>Loading</p>
  </Section>
}

Я пробовал эти 2, но ни один из них не подходит для моего варианта использования.

1 <script> отображается, но не выполняется

<div dangerouslySetInnerHTML={{ __html: data.html }}/>

2

Реагирует: тег Script не работает при вставке с использованием dangerouslySetInner HTML

Это не работает для моего случая. Что если у меня есть теги типа <script src="https://gist.github.com/ogyalcin/66d0785998588ab50cf1908f8d43bb7b.js"></script>, чтобы визуализировать блок кода между двумя абзацами? Кроме того, трудно справиться, если в теге есть больше атрибутов.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Может помочь:

Пример кода из проекта создания-реакции-приложения.

import React, { useEffect } from 'react';
import './App.css';

function App() {
  const danger = '<script>alert("Hello world!")</script>';

  useEffect(() => {
    const el = document.querySelector('.danger');
    el.appendChild(document.createRange().createContextualFragment(danger));
  }, []);

  return (
    <div className='App'>
      <h1>Render and execute script tag</h1>
      <div className='danger'></div>
    </div>
  );
}

export default App;

Edit trusting-dream-i9ozk

Может также быть библиотекой для этого:

опасно-установлен- html -контент

import React from 'react'
import InnerHTML from 'dangerously-set-html-content'

function Example {

  const html = `
    <div>This wil be rendered</div>
    <script>
      alert('testing')
    </script>
  `

  return (
    <InnerHTML html={html} />
  )
}

Это также будет работать для скриптов с sr c атрибут set it

Обмен хорошей статьей для получения дополнительной информации: Визуализация опасного содержимого с помощью React

Отображение опасности

Сейчас что происходит, когда вы хотите использовать опасно SetInner HTML, но также должны выполнить любой тег сценария, который находится внутри html? Это противоречит спецификациям HTML5, но если мы немного покопаемся в том, что делает внутренний HTML для инъекции html, мы можем найти что-то интересное:

Указанное значение анализируется как HTML или XML (в зависимости от типа документа), в результате чего объект DocumentFragment представляет новый набор узлов DOM для новых элементов.

Этот DocumentFragment представляет собой облегченную версию документа, он может иметь дочерние узлы, Основное отличие состоит в том, что, поскольку он является фрагментом, фактически не является частью активного / основного документа.

Мы можем создать DocumentFragment с помощью API document.Range.

import React, { useEffect, useRef } from 'react'

// InnerHTML component
function InnerHTML(props) {
  const { html } = props
  const divRef = useRef(null)

  useEffect(() => {
    const parsedHTML = document.createRange().createContextualFragment> (html)
    divRef.current.appendChild(parsedHTML)
  }, [])


  return (
    <div ref={divRef}></div>
  )
}

// Usage
function App() {
  const html = `
    <h1>Fragment</h1>
  `

  return (
    <InnerHTML html={html} />
  )
}

Ссылка на внутренний HTML

0 голосов
/ 13 апреля 2020

Не ответ, просто немного отзывов к вашему сведению. Я провел эксперимент внутри браузера. Похоже, что скрипт скрипт отображается. Однако код внутри не выполняется, не знаю почему.

// @jsx

function App() {
  return <div><h1>React</h1><div dangerouslySetInnerHTML={{ __html: window.thatScript }} /><h2>JS</h2></div>
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
<script>
window.thatScript = '<script type="text/javascript">function foo() {console.log("yolo")} setTimeout(() => foo()};<\script>'
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...