为了账号安全,请及时绑定邮箱和手机立即绑定

iFrame 中的 Service Worker

iFrame 中的 Service Worker

慕工程0101907 2021-08-20 18:07:59
我正在尝试在 iframe 中初始化一个 service worker。我知道 Service Worker 在起源方面有安全限制,但据我所知,设置base应该可以解决这个问题。<html>   <base href="http://127.0.0.1:9090">   <script>     if ('serviceWorker' in navigator) {        window.addEventListener('load', function() {          navigator.serviceWorker.register('/sw.js').then(function(reg) {            if(reg.installing) {              console.log('Service worker installing');            } else if(reg.waiting) {              console.log('Service worker installed');            } else if(reg.active) {              console.log('Service worker active');              console.log(self)            }          }).catch(function(error) {            // registration failed            console.log('Registration failed with ' + error);          });        });      }   </script>错误: Registration failed with InvalidStateError: Failed to register a ServiceWorker: The document is in an invalid state.如果我修改 base,它会抱怨起源不一样,所以 service worker 与 base href 有一定的联系。我在这里缺少什么?
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

<base>元素不会更改文档的来源。您可以通过记录来测试这一点self.origin

什么<base>没有做,但是,更改解析相对URL的基本URL。在这种情况下,您的 Service Worker 脚本是一个相对 URL。因此,而不是相对self.location于其相对于新基地。

这意味着如果您提供<base>跨域 URL,那么您的 Service Worker 脚本也将是跨域的。这将在您尝试注册时触发错误。


查看完整回答
反对 回复 2021-08-20
?
手掌心

TA贡献1942条经验 获得超3个赞

我将发布我对错误的观察,Failed to register a ServiceWorker: The document is in an invalid state.因为我找不到关于错误的太多信息。


当 iframe 被动态添加到文档中时,从该 iframe 注册 service worker 将导致上述错误。例如:


var iframe = document.createElement('iframe');


var html = 

`<head>

    <script src="./index.js" ></script>

</head>

<body>Foo</body>`;

document.body.appendChild(iframe);

iframe.contentWindow.document.open();

iframe.contentWindow.document.write(html);

iframe.contentWindow.document.close();

与在父 html 中静态地拥有 iframe 不同,服务注册将在其中工作。


<html>

    <head></head>

    <body>  

        <iframe>

            <html>

                <head>

                    <script src="./index.js"></script>

                </head>

                <body>

                    <h4>Foo</h4>

                </body>

            </html>

        </iframe>

    </body>

</html>

Service Worker 注册代码在 index.js 中,如下所示:


if ('serviceWorker' in navigator) {

    navigator.serviceWorker.register('/sw.js')

    .then((reg) => {

        // registration worked

        console.log('Registration succeeded. Scope is ' + reg.scope);

    }).catch((error) => {

        // registration failed

        console.log('Registration failed with ' + error);

    });

}

如果allow-same-origin启用了沙箱,第二种情况甚至可以使用沙箱 iframe 。


查看完整回答
反对 回复 2021-08-20
  • 2 回答
  • 0 关注
  • 508 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信