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