[英]Writing HTML content with document.write from external script in React
我嘗試了多種方法,我正在嘗試從 tryhackme 集成我的橫幅,或者讓我們說從任何平台我們得到一個我們想要集成的腳本 src 但 react 沒有渲染它。
<script src="https://tryhackme.com/badge/170258"></script>
這是我的 reactjs 代碼塊
import React, { Component } from "react";
// const Awards = (props) => {
// return (
// <Container>
// <div>
// {/* <img src="https://tryhackme-badges.s3.amazonaws.com/rootsid.png" alt="TryHackMe"></img> */}
// </div>
// </Container>
// )
// }
// const Container = styled.main`
// color: white;
// `;
export default class Awards extends Component {
componentDidMount() {
const script = document.createElement("script");
script.src = "https://tryhackme.com/badge/170258";
script.async = true;
var scripttag = document.getElementById('scriptTarget')
scripttag.appendChild(script);
}
render() {
return (
<div>
<div id="scriptTarget" />
<div className="main">
// Other stuff
</div>
</div>
);
}
}
我試圖在 react js 中包含腳本標記,而不是圖像 src,因此它可以是動態的。 我試過helmet
, react-safe
但無法讓它工作。 這也是小提琴鏈接。
https://jsfiddle.net/h2x5pkfy/
終於設法讓它工作了! 首先,該腳本僅包含一個表達式: document.write(window.atob(<BASE64 encoded content forming a HTML subtree>))
。
建議鏈接中的解決方案有效,只是允許外部腳本寫入您的文檔並不簡單。
執行此操作時收到的錯誤是170258:1 Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
. write
上的文檔說write
需要打開和關閉已加載的文檔,例如
document.open()
document.write(...)
document.close()
...它還說這是在加載的document.write
上使用document.write
時隱式完成的,但是,錯誤消息說它必須是外部腳本時的顯式調用。 盡管如此,如果腳本加載並執行,它會覆蓋整個頁面,從而刪除 React 應用程序......使用 React 加載一個刪除 React 的腳本似乎有點奇怪。
由於 OP 無法修改原始腳本並插入必要的調用(不確定這是否足夠),因此這不是一個選項。 一種想法是嘗試將腳本作為文本導入,然后提取 Base64 編碼的字符串並在內部使用它(這會起作用)。 盡管如此,因為它會刪除 React 應用程序,所以我真的不明白這一點。
為了不執行一些奇怪的 hack 並保持 React 應用程序到位,可以使用 iFrame。 iFrame 可以引用如下文檔:
<!DOCTYPE html>
<html>
<body>
<script src="https://tryhackme.com/badge/170258"></script>
</body>
</html>
只需將其添加到 React 即可按預期工作
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<div>
<h1>React output before the iFrame</h1>
<iframe src={"frame.html"} style={{"borderWidth": 0}}></iframe>
<h1>React output after the IFrame</h1>
</div>,
document.getElementById('root')
);
</script>
</body>
</html>
...產生輸出
然而,當谷歌搜索一下 React 中的 iFrame 時,很容易遇到一些用例,在這種情況下,會出現阻止請求的不同類型的問題,在這種情況下,人們可能必須采取一些額外的措施來使 iFrame 正常運行。
總而言之,我認為這個用例有點不尋常,就我個人而言,我會嘗試以完全不同的方式解決它,但鑒於上下文就是這樣,這絕對是一種方法。
為了避免使用為一個單獨的文件iframe
中, srcDoc
屬性可以在使用iframe
讓你在線,而不是指定的內容,在這一點上,我們在抵達以下作用組件,而不是:
export default function App() {
const iFrame = '<div><script src="https://tryhackme.com/badge/170258"></script></div>';
return (
<div>
<h1>React output before the iFrame</h1>
<iframe title={"badge"} srcDoc={iFrame} style={{ borderWidth: 0 }}>
</iframe>
<h1>React output after the IFrame</h1>
</div>
);
}
這個解決方案可以在這個沙箱中看到。 向iframe
元素添加更多樣式,使其根據需要融入。
最后,相應的單文件獨立解決方案(注意內容字符串傳遞所必需的轉義script
結束標記):
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const iFrame = `<div><script src="https://tryhackme.com/badge/170258"><\/script></div>`
ReactDOM.render(
<div>
<h1>React output before the iFrame</h1>
<iframe title={"badge"} srcDoc={iFrame} style={{"borderWidth": 0}}></iframe>
<h1>React output after the IFrame</h1>
</div>,
document.getElementById('root')
);
</script>
</body>
</html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.