我有从后端获取的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种方法,但是它们都不适合我的用例。
<script>
已呈现但未执行<div dangerouslySetInnerHTML={{ __html: data.html }}/>
React: Script tag not working when inserted using dangerouslySetInnerHTML
这不适用于我的情况。如果我有类似的标签怎么办
<script src="https://gist.github.com/ogyalcin/66d0785998588ab50cf1908f8d43bb7b.js"></script>
以便在两个段落之间呈现代码块?此外,如果标签内还有更多属性,则很难处理。
答案 0 :(得分:0)
不是答案,只是一些反馈。我在浏览器中做了一个实验。好像脚本标记已呈现。但是里面的代码没有执行,不知道为什么。
// @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>
答案 1 :(得分:0)
可能有帮助:
来自create-react-app项目的示例代码。
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;
可能还有一个图书馆:
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} /> ) }
这同样适用于设置了src属性的脚本
分享好文章以获取更多信息: Render dangerous content with React
带来危险
现在,当您想危险地使用SetInnerHTML但又需要执行html内的任何脚本标签时会发生什么?这违反了HTML5规范,但是如果我们进一步研究innerHTML注入HTML的方式,我们会发现一些有趣的东西:
将指定的值解析为HTML或XML(基于文档类型),从而生成一个DocumentFragment对象,该对象代表新元素的新DOM节点集。
此DocumentFragment是文档的轻量级版本,它可以具有子节点,主要区别在于,由于是片段,因此实际上不是活动/主文档的一部分。
我们可以使用document.Range API创建一个DocumentFragment。
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} /> ) }