clients.openWindow()“不允许打开窗口”。在一个serviceWorker谷歌浏览器 [英] clients.openWindow() "Not allowed to open a window." on a serviceWorker Google Chrome
问题描述
我正在Chrome版本42.0.2311.152m下进行测试,并且想要实现在此示例中的通知类型中打开窗口:(source: 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();
//这看起来是看当前是否已经打开,
//如果是
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:不允许打开一个窗口。,
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()});
我收到错误消息:
<$ p $ {code:15,
message:不允许关注窗口,
name:InvalidAccessError}
我认为问题在于url不仅仅是'/'。你有什么想法吗?
非常感谢你!
祝你好运
Andi
你的代码适合我,所以我将解释使用 openWindow
/ focus
,以及如何避免不允许[open | focus]窗口错误消息。
clients.openWindow()
和 windowClient.focus()
点击通知后(至少在Chrome 47中),并且在点击处理程序期间至多可以调用这些方法中的一个。此行为在 https://github.com/slightlyoff/ServiceWorker/issues/602。
如果您的 openWindow
/ focus
拒绝并显示错误消息
不允许打开窗口。 for
openWindow
不允许关注窗口。 forfocus
然后你没有满足 openWindow
/ focus
。例如(所有的点也适用于焦点
,而不仅仅是 openWindow
)。
$
-
openWindow
在通知未被点击时被调用。 c $ c> openWindow 在notificationclick
处理程序返回后调用,并且您没有调用event.waitUntil $
openWindow
在承诺传递给event.waitUntil
已解决。
- 承诺未解决,但耗时太长( Chrome中的10秒),因此调用
openWindow
的临时权限已过期。
确实需要 openWindow
/ 在
。 notificationclick
处理程序完成之前,最多只会调用焦点
我之前说过,问题wo中的代码rks,所以我会展示另一个带注释的例子。
$ b
// serviceworker.js
self.addEventListener('notificationclick',function(event){
//关闭通知。
event.notification.close();
//示例:3秒后打开窗口。
//(这样做是非常糟糕的用户体验,因为
//用户不知道3秒钟会发生什么。)
var promise = new Promise(function(resolve ){
setTimeout(resolve,3000);
})。then(function(){
//返回openWindow返回的promise,以防万一
//打开任何来源只适用于Chrome 43+。
return clients.openWindow('https://example.com');
});
//现在等待承诺保持许可权。
event.waitUntil(promise);
});
index.html
< button id =show-notification-btn>显示通知< / 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){
//显示通知如果用户点击在这个
//通知,然后通知点击被解雇。
registration.showNotification('Test');
});
}
});
}
< / script>
PS。服务人员仍在开发中,所以值得一提的是,我已经验证上述评论在Chrome 49中是正确的,并且该示例在Chrome 43+中运行(并打开 /
而不是 https://example.com
也适用于Chrome 42)。
I'm testing under Chrome Version 42.0.2311.152m and I want to implement to open a window on a notificationclick like in this example: (source: 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('/');
}));
});
My filestructure is like:
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
I have the issue that I always get an
InvalidAccessError
when calling clients.openWindow('/') or clients.openWindow('https://myurl.no-ip.org/app/index.html') in the service-worker.js, I receive the error:
{code: 15,
message: "Not allowed to open a window.",
name: "InvalidAccessError"}
The "return client.focus()" line is never reached because the client.url is never just '/'. Looking at
clients.matchAll({type: "window"})
.then(function (clientList) {
console.log(clientList[0])});
I see my current WindowClient:
{focused: false,
frameType: "top-level",
url: "https://myurl.no-ip.org/app/index.html",
visibilityState: "hidden" }
The properties 'focused' and 'visibilityState' are correct and change correctly.
By doing a manual focus call
clients.matchAll({type: "window"})
.then(function (clientList) {
clientList[0].focus()});
I receive the error:
{code: 15,
message: "Not allowed to focus a window.",
name: "InvalidAccessError"}
I think the problem is that url is not just '/'. Do you have any ideas for that?
Thank you very much!
Best regards
Andi
Your code works fine for me, so I'll explain the requirements for using openWindow
/ focus
, and how you can avoid the "Not allowed to [open|focus] a window" error message.
clients.openWindow()
and windowClient.focus()
are only allowed after clicking the notification (in Chrome 47 at least), and at most one of these methods can be called, for the duration of the click handler. This behavior was specified in https://github.com/slightlyoff/ServiceWorker/issues/602.
If your openWindow
/ focus
call is rejected with error message
"Not allowed to open a window." for
openWindow
"Not allowed to focus a window." forfocus
then you didn't satisfy the requirements of openWindow
/ focus
. For example (all points also apply to focus
, not just openWindow
).
openWindow
was called while the notification wasn't clicked.openWindow
was called after thenotificationclick
handler returned, and you did not callevent.waitUntil
with a promise.openWindow
was called after the promise passed toevent.waitUntil
was resolved.- The promise was not resolved, but it took "too long" (10 seconds in Chrome), so the temporary permission to call
openWindow
expired.
It is really necessary that openWindow
/ focus
is called at most once, and before the notificationclick
handler finishes.
As I said before, the code in the question works, so I'll show another annotated example.
// 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 are still in development, so it's worth mentioning that I've verified that the above remarks are correct in Chrome 49, and that the example works in Chrome 43+ (and opening /
instead of https://example.com
also works in Chrome 42).
这篇关于clients.openWindow()“不允许打开窗口”。在一个serviceWorker谷歌浏览器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!