клиенты.openWindow () " не разрешается открывать окно."на serviceWorker Гугл Хром
Я тестирую в Chrome версии 42.0.2311.152 m, и я хочу реализовать, чтобы открыть окно на notificationclick, как в этом примере: (источник: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('/');
}));
});
мой filestructure является 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
у меня есть проблема, что я всегда получаю
InvalidAccessError
при вызове клиентов.openWindow ( ' /') или клиенты.openWindow ('https://myurl.no-ip.org/app/index.html') в сервис-работнике.js, я получаю ошибка:
{code: 15,
message: "Not allowed to open a window.",
name: "InvalidAccessError"}
"возвращения клиента.focus () " линия никогда не достигается, потому что клиент.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-адрес не просто'/'. У вас есть идеи для это?
большое спасибо!
С наилучшими пожеланиями
Анди
1 ответов
ваш код отлично работает для меня, поэтому я объясню требования для использования openWindow
/ focus
, и как вы можете избежать сообщения об ошибке" не разрешено [открывать|фокусировать] окно".
clients.openWindow()
и windowClient.focus()
разрешены только после нажатия на уведомление (по крайней мере, в Chrome 47), и не более один из этих методов можно вызвать, на время работы обработчика click. Это поведение было указано в https://github.com/slightlyoff/ServiceWorker/issues/602.
если openWindow
/ focus
отклонить вызов с сообщением об ошибке
" не разрешается открывать окно.- за
openWindow
- Нельзя фокусировать окно.- заfocus
тогда вы не удовлетворяли требованиям openWindow
/ focus
. Например (все точки также относятся к focus
не только openWindow
).
-
openWindow
был звонил, когда уведомление не было нажато. -
openWindow
названиеnotificationclick
обработчик вернулся, и вы не позвонилиevent.waitUntil
с обещанием. -
openWindow
был вызван после того, как обещание перешло кevent.waitUntil
был решен.
10 секунд в Chrome), поэтому временное разрешение на вызов
openWindow
истек.
это действительно необходимо, что openWindow
/ focus
вызывается не более одного раза, а перед notificationclick
обработчик закончит работу.
как я уже говорил, код в вопросе работает, поэтому я покажу еще один аннотированный пример.
// 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. Сервисные работники все еще находятся в разработке, поэтому стоит отметить, что я проверил, что вышеуказанные замечания верны в Chrome 49, и что пример работает в Chrome 43+ (и открытие /
вместо https://example.com
также работает в Chrome 42).