我正在try 制作一个可加载的小部件,该小部件将在单击按钮时调用API.

小部件页面本身

widget.html

<html>
<head>
    <title>Widget</title>
</head>
<body>
<button id="test"></button>

<script>
    window.onload = init;

    function clicked() {
        // some logic
    }

    function init() {
        document.getElementById('test').addEventListener('click', clicked, false);
    }

    export {clicked}
</script>

</body>
</html>

它嵌入的页面

index.html

<!DOCTYPE HTML>
<html>
<head>
    <title>Getting started</title>
</head>
<body>
<div>
    <div id="widget_box"></div>
    <script src="http://localhost:8080/js/widget.js" type="text/javascript"></script>
    <script type="text/javascript">wdgt.init('widget_box');</script>
</div>

</body>
</html>

加载小部件的JS代码

widget.js

var wdgt= {
    idBox: 'wdgt',
    url_widget: 'http://localhost:8080/pages/widgets/widget.html',
    url_style: 'http://localhost:8080/css/widget.css',

    init: function (id) {
        console.log("Begin Widget initialization");

        if (!id) {
            id = this.idBox;
        }

        if (document.getElementById(id)) {

            this.addStyle();
            try {
                var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
                var xhr = new XHR();
                xhr.open('GET', this.url_widget, true);

                xhr.onload = function () {
                    if (this.response) {
                        document.getElementById(id).innerHTML = this.response;
                    }
                }

                xhr.onerror = function () {
                    console.log('onerror ' + this.status);
                }

                xhr.send();
            } catch (ignore) {
            }
        } else {
            console.log('The specified block id="' + id + '" is missing');
        }
    },

    addStyle: function () {
        style = document.createElement('link');
        style.rel = 'stylesheet';
        style.type = 'text/css';
        style.href = this.url_style;
        document.head.appendChild(style);
    }
}

如果我在单独的窗口中打开小部件,则附加到按钮的代码可以正常工作.但当我试图嵌入它时,什么也没有发生. 此外,在此脚本中,document.getElementById()在try 查找按钮时返回NULL.

后面是一个简单的Spring应用程序,它返回index.html

推荐答案

这是不应该起作用的.您应该使用iframe元素来获取和呈现外部页面.

您的脚本widget.js正在try 将获取的widget.html的内容呈现为<div>元素.

浏览器将尽最大努力,尽管它不能在<div>以内创建另一个DOM树.因为当您将整个HTML页面提供给innerHTML时,基本上是要求浏览器在文档中呈现文档.这是不允许的.

尽管如此,它仍将呈现文档正文的内容.这样你就能看到按钮了.但它不会执行任何<script>个标签.这是防止XSS攻击的安全措施.确实存在几种执行代码的肮脏方法,但我不推荐它们.

那么,您应该如何将外部小部件添加到页面中呢?答案很简单:见见<iframe>人吧!这家伙就是为这些东西而生的.对于您的情况,您应该这样重写index.html:

<!DOCTYPE HTML>
<html>
<head>
    <title>Getting started</title>
</head>
<body>
    <iframe src="http://localhost:8080/pages/widgets/widget.html" width="800" height="600"></iframe>
</body>
</html>

使用iframe,您不需要手动获取小部件的HTML.浏览器会将其下载并呈现在您的iframe中.就像包含所有样式、嵌入资源和脚本的文档中的文档一样.

请注意,当您使用IFRAME嵌入某些内容时,会受到安全限制.你将不能直接从iFrame内部与你的主页交互,反之亦然.它就像是文档中的一个单独窗口.而且它还会有额外的限制.请把地址打到the docs.

Javascript相关问答推荐

如何最好地从TypScript中的enum获取值

从实时数据库(Firebase)上的子类别读取数据

拖放仅通过 Select 上传

JQuery. show()工作,但. hide()不工作

colored颜色 检测JS,平均图像 colored颜色 检测JS

当作为表达式调用时,如何解析方法decorator 的签名?

MathJax可以导入本地HTML文档使用的JS文件吗?

html + java script!需要帮助来了解为什么我得到(无效的用户名或密码)

覆盖TypeScrip中的Lit-Element子类的属性类型

WhatsApp Cloud API上载问题:由于MIME类型不正确而导致接收&Quot;INVALID_REQUEST";错误

Eval vs函数()返回语义

如何将数组用作复合函数参数?

为什么当我更新数据库时,我的所有组件都重新呈现?

在验证和提交表单后使用useNavigate()进行react 重定向,使用带有加载器和操作的路由

为什么我不能使用其同级元素调用和更新子元素?

是否设置以JavaScript为背景的画布元素?

ComponentWillReceiveProps仍在React 18.2.0中工作

在高位图中显示每个y轴系列的多个值

CSS网格使页面自动滚动

Node.js的Fetch()调用总是创建新的Express会话