Clients.openWindow () "It is not allowed to open a window." on the Google Chrome Worker service

I am testing in Chrome Version 42.0.2311.152m, and I want to implement to open a window on a notification, as 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 philology is similar:
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 a problem that I always get

InvalidAccessError

when calling clients.openWindow ('/') or clients.openWindow (' https://myurl.no-ip.org/app/index.html ') in service-worker.js, I get an error message:

 {code: 15, message: "Not allowed to open a window.", name: "InvalidAccessError"} 

The line "return client.focus ()" is never reached, because client.url is never "/". 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 "focused" and "visibility" properties are correct and correct. When making a manual focus call

 clients.matchAll({type: "window"}) .then(function (clientList) { clientList[0].focus()}); 

I get an error message:

 {code: 15, message: "Not allowed to focus a window.", name: "InvalidAccessError"} 

I think the problem is that the URL is not just "/". Do you have any ideas for this?

Many thanks!
Regards, Andi

+5
source share
1 answer

Your code works fine for me, so I will explain the requirements for using openWindow / focus and how you can avoid the error message "Not allowed [open | focus] in window".

clients.openWindow() and windowClient.focus() allowed only after clicking on the notification (at least in Chrome 47) and no more than one of these methods can be called throughout the click handler.This behavior was specified in https: // github .com / slightlyoff / ServiceWorker / issues / 602 .

If your openWindow / focus call is rejected with an error message

"It is not allowed to open a window." for openWindow
"Not allowed to focus the window." for focus

then you did not meet the requirements of openWindow / focus . For example (all points also refer to focus , not just openWindow ).

  • openWindow was called until a notification was pressed.
  • openWindow is called after the notificationclick handler returns, and you did not call event.waitUntil with a promise.
  • openWindow was called after the promise passed to event.waitUntil .
  • The promise was not resolved, but it took too much time ( 10 seconds in Chrome ), so the temporary permission to call openWindow expired.

In fact, it is necessary that openWindow / focus called no more than once before the notificationclick handler is executed.

As I said, the code in the question works, so I'll show you 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 confirmed that the above comments 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).

+20
source

All Articles