簡體   English   中英

如何將外部 js 代碼嵌入到 React 組件中

[英]How to embed external js code into React component

我正在一個項目中工作,我必須使用RIPE Stat提供的 widget_api 代碼將圖形小部件集成到 React 組件中。 例如在 HTML5 中,我會這樣做,並且效果很好。

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Widget</title>
</head>
<body>
    
    <script src="https://stat.ripe.net/widgets/widget_api.js"></script>
    <div class="statwdgtauto">
        <script>
            ripestat.init("rir-geo",{"resource":"80.12.67.0/24"},null,{"size":"500","disable":["controls"]})
        </script>
    </div>
</body>
</html>

在進行研究時,我發現了這個反應安全的庫,它允許在 React 中做同樣的事情

這是我的索引文件的代碼。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
   
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>MyWHOIS</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  </head>
  <body class="bd-home">
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./js/polyfill.js" defer ></script>
    <script src="https://stat.ripe.net/widgets/widget_api.js" async></script>
  </body>

</html>

而我創建的組件...

import React, { Component } from 'react';
import Safe from "react-safe";

export default class EmbedComponent extends Component {
    constructor(props){
        super();
        /*
        const widget_api = document.createElement("script");
        widget_api.src = "https://stat.ripe.net/widgets/widget_api.js";
        widget_api.async = true;
    
        document.body.appendChild(widget_api);
       */
    }

    render() {
        const params1 = {"family":4,"warnings":1,"delegated":1,"resource":"FR"};
        const params2 ={"resource":"127.0.0.1/24"};
        const control = {"size":"500","disable":["controls"]};
        return (
            <div>
                <h4>Include Embed</h4>
                <div className="statwdgtauto">
                    <Safe.script>
                        {`ripestat.init("rpki-by-country",${params1},null,${control})`}
                    </Safe.script>
                    <Safe.script>
                        {`ripestat.init("rir-geo",${params2},null,${control})`}
                    </Safe.script>
                </div>
            </div>
        )
    }
}

我有錯誤,當我包含帶有 async 或 defer 標記的文件時,我有一個 cors 錯誤

通過 document.write 調用一個解析器阻塞、跨站點(即不同的 eTLD+1)腳本。 由於網絡連接不佳,此腳本的網絡請求可能會在此或將來的頁面加載中被瀏覽器阻止。 如果在此頁面加載中被阻止,將在后續控制台消息中確認。 有關更多詳細信息,請參閱。

並且沒有延遲或異步我在文檔上寫這個問題

無法在“文檔”上執行“寫入”:除非顯式打開,否則無法從異步加載的外部腳本寫入文檔。 小部件_api.js:90

定義一個新的 state isLoading

constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
    };
}

componentDidMount() {
  const widget_api = document.createElement("script");
  widget_api.src = "https://stat.ripe.net/widgets/widget_api.js";
  widget_api.async = true;
  // Wait for the onload here
  widget_api.script.onload = () => setState({isLoading: false})
  document.body.appendChild(widget_api);
}

並在你渲染 function 在 isLoading 階段做一些事情(你可以顯示一個加載器而不是你當前的實現)

這里的問題是您被鎖定在成熟狀態的實現細節中,這會阻止在某些ripeStat框架中使用它,例如反應。

如果您查看ripeStat代碼,例如https://stat.ripe.net/widgets/widget_api.js ,您會看到它調用了document.write

document.write在延遲情況下不會啟動,並且是預期的。在此處查看https://developer.mozilla.org/en-US/docs/Web/API/Document/write#notes ,您會發現相同的錯誤你所看到的。

在此處輸入圖像描述

一旦文檔被讀取、解析和關閉, document.write調用將不會被受理。

我認為這是ripeStat庫的限制。 他們應該使用的是

const script = document.createElement('script');
script.src = 'https://stat.ripe.net/widgets/widget_api.js';
document.head.appendChild(script);

這將確保它全面正確地工作。

另一種可能更好的選擇是來自成熟統計的 npm ripeStat ,這將有助於現代框架。

它現在在您的反應應用程序中正常工作的唯一方法是腳本必須在瀏覽器開始解析您的 HTML 並解釋它之前存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM