clients.openWindow() "Not allowed to open a window." 在 serviceWorker Google Chrome
clients.openWindow() "Not allowed to open a window." on a serviceWorker Google Chrome
我正在 Chrome 版本 42.0.2311.152m 下进行测试,我想实现在通知点击上打开 window,就像这个例子中那样:(来源:https://developer.mozilla.org/en-US/docs/Web/API/WindowClient
)
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(clients.matchAll({
type: "window"
}).then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow)
return clients.openWindow('/');
}));
});
我的文件结构如下:
https://myurl.no-ip.org/app/index.html
https://myurl.no-ip.org/app/manifest.json
https://myurl.no-ip.org/app/service-worker.js
我遇到的问题是我总是收到
InvalidAccessError
在服务中调用 clients.openWindow('/') 或 clients.openWindow('https://myurl.no-ip.org/app/index.html') 时-worker.js,我收到错误:
{code: 15,
message: "Not allowed to open a window.",
name: "InvalidAccessError"}
永远不会到达 "return client.focus()" 行,因为 client.url 永远不会只是“/”。
看着
clients.matchAll({type: "window"})
.then(function (clientList) {
console.log(clientList[0])});
我看到我当前的 WindowClient:
{focused: false,
frameType: "top-level",
url: "https://myurl.no-ip.org/app/index.html",
visibilityState: "hidden" }
属性 'focused' 和 'visibilityState' 正确且更改正确。
通过手动调用对焦
clients.matchAll({type: "window"})
.then(function (clientList) {
clientList[0].focus()});
我收到错误:
{code: 15,
message: "Not allowed to focus a window.",
name: "InvalidAccessError"}
我认为问题在于 url 不仅仅是“/”。你对此有什么想法吗?
非常感谢!
最好的问候
安迪
您的代码对我来说工作正常,所以我将解释使用 openWindow
/ focus
的要求,以及如何避免 "Not allowed to [open|focus] a window" 错误消息。
clients.openWindow()
和 windowClient.focus()
仅在点击通知后允许(至少在 Chrome 47),最多 一个 在单击处理程序的持续时间内可以调用这些方法。此行为在 https://github.com/slightlyoff/ServiceWorker/issues/602.
中指定
如果您的 openWindow
/ focus
呼叫被拒绝并显示错误消息
"Not allowed to open a window." for openWindow
"Not allowed to focus a window." for focus
那你不满足openWindow
/focus
的要求。例如(所有分数也适用于 focus
,而不仅仅是 openWindow
)。
openWindow
在未单击通知时被调用。
openWindow
是在 notificationclick
处理程序返回后调用的,而您没有使用承诺调用 event.waitUntil
。
openWindow
在传递给 event.waitUntil
的承诺得到解决后被调用。
- promise没有解决,但是用了"too long"(10 seconds in Chrome),所以调用
openWindow
的临时权限过期了。
确实有必要在 notificationclick
处理程序完成之前最多调用一次 openWindow
/ focus
。
正如我之前所说,问题中的代码有效,所以我将展示另一个带注释的示例。
// serviceworker.js
self.addEventListener('notificationclick', function(event) {
// Close notification.
event.notification.close();
// Example: Open window after 3 seconds.
// (doing so is a terrible user experience by the way, because
// the user is left wondering what happens for 3 seconds.)
var promise = new Promise(function(resolve) {
setTimeout(resolve, 3000);
}).then(function() {
// return the promise returned by openWindow, just in case.
// Opening any origin only works in Chrome 43+.
return clients.openWindow('https://example.com');
});
// Now wait for the promise to keep the permission alive.
event.waitUntil(promise);
});
index.html
<button id="show-notification-btn">Show notification</button>
<script>
navigator.serviceWorker.register('serviceworker.js');
document.getElementById('show-notification-btn').onclick = function() {
Notification.requestPermission(function(result) {
// result = 'allowed' / 'denied' / 'default'
if (result !== 'denied') {
navigator.serviceWorker.ready.then(function(registration) {
// Show notification. If the user clicks on this
// notification, then "notificationclick" is fired.
registration.showNotification('Test');
});
}
});
}
</script>
PS。 Service workers 仍在开发中,所以值得一提的是,我已经验证了上述评论在 Chrome 49 中是正确的,并且该示例在 Chrome 43+ 中有效(并且打开 /
而不是 https://example.com
也适用于 Chrome 42).
我正在 Chrome 版本 42.0.2311.152m 下进行测试,我想实现在通知点击上打开 window,就像这个例子中那样:(来源:https://developer.mozilla.org/en-US/docs/Web/API/WindowClient )
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(clients.matchAll({
type: "window"
}).then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow)
return clients.openWindow('/');
}));
});
我的文件结构如下:
https://myurl.no-ip.org/app/index.html
https://myurl.no-ip.org/app/manifest.json
https://myurl.no-ip.org/app/service-worker.js
我遇到的问题是我总是收到
InvalidAccessError
在服务中调用 clients.openWindow('/') 或 clients.openWindow('https://myurl.no-ip.org/app/index.html') 时-worker.js,我收到错误:
{code: 15,
message: "Not allowed to open a window.",
name: "InvalidAccessError"}
永远不会到达 "return client.focus()" 行,因为 client.url 永远不会只是“/”。 看着
clients.matchAll({type: "window"})
.then(function (clientList) {
console.log(clientList[0])});
我看到我当前的 WindowClient:
{focused: false,
frameType: "top-level",
url: "https://myurl.no-ip.org/app/index.html",
visibilityState: "hidden" }
属性 'focused' 和 'visibilityState' 正确且更改正确。
通过手动调用对焦
clients.matchAll({type: "window"})
.then(function (clientList) {
clientList[0].focus()});
我收到错误:
{code: 15,
message: "Not allowed to focus a window.",
name: "InvalidAccessError"}
我认为问题在于 url 不仅仅是“/”。你对此有什么想法吗?
非常感谢!
最好的问候
安迪
您的代码对我来说工作正常,所以我将解释使用 openWindow
/ focus
的要求,以及如何避免 "Not allowed to [open|focus] a window" 错误消息。
clients.openWindow()
和 windowClient.focus()
仅在点击通知后允许(至少在 Chrome 47),最多 一个 在单击处理程序的持续时间内可以调用这些方法。此行为在 https://github.com/slightlyoff/ServiceWorker/issues/602.
如果您的 openWindow
/ focus
呼叫被拒绝并显示错误消息
"Not allowed to open a window." for
openWindow
"Not allowed to focus a window." forfocus
那你不满足openWindow
/focus
的要求。例如(所有分数也适用于 focus
,而不仅仅是 openWindow
)。
openWindow
在未单击通知时被调用。openWindow
是在notificationclick
处理程序返回后调用的,而您没有使用承诺调用event.waitUntil
。openWindow
在传递给event.waitUntil
的承诺得到解决后被调用。- promise没有解决,但是用了"too long"(10 seconds in Chrome),所以调用
openWindow
的临时权限过期了。
确实有必要在 notificationclick
处理程序完成之前最多调用一次 openWindow
/ focus
。
正如我之前所说,问题中的代码有效,所以我将展示另一个带注释的示例。
// serviceworker.js
self.addEventListener('notificationclick', function(event) {
// Close notification.
event.notification.close();
// Example: Open window after 3 seconds.
// (doing so is a terrible user experience by the way, because
// the user is left wondering what happens for 3 seconds.)
var promise = new Promise(function(resolve) {
setTimeout(resolve, 3000);
}).then(function() {
// return the promise returned by openWindow, just in case.
// Opening any origin only works in Chrome 43+.
return clients.openWindow('https://example.com');
});
// Now wait for the promise to keep the permission alive.
event.waitUntil(promise);
});
index.html
<button id="show-notification-btn">Show notification</button>
<script>
navigator.serviceWorker.register('serviceworker.js');
document.getElementById('show-notification-btn').onclick = function() {
Notification.requestPermission(function(result) {
// result = 'allowed' / 'denied' / 'default'
if (result !== 'denied') {
navigator.serviceWorker.ready.then(function(registration) {
// Show notification. If the user clicks on this
// notification, then "notificationclick" is fired.
registration.showNotification('Test');
});
}
});
}
</script>
PS。 Service workers 仍在开发中,所以值得一提的是,我已经验证了上述评论在 Chrome 49 中是正确的,并且该示例在 Chrome 43+ 中有效(并且打开 /
而不是 https://example.com
也适用于 Chrome 42).