有没有办法从服务工作者播放音频文件?
我正在尝试使用 io.sound 库,但它是一个需要 window 的JavaScript插件,所以它不起作用。
修改
正如Jeff所建议的,我正在尝试打开一个新窗口并向该窗口发布消息。这是我的代码:
function notifyClientToPlaySound() {
idbKeyval.get('pageToOpenOnNotification')
.then(url => {
console.log("notifyClientToPlaySound", url);
clients.matchAll({
type: "window"
//includeUncontrolled: true
})
.then((windowClients) => {
console.log("notifyClientToPlaySound - windowClients", windowClients);
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && "focus" in client) {
notify({ event: "push" });
return client.focus();
}
}
//https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow
if (clients.openWindow) {
return clients.openWindow("/")
.then(() => {
notify({ event: "push" });
});
}
})
});
}
现在从 self.addEventListener中的 event.waitUntil(..)调用此函数(“push”,(event)=&gt; {...}
self.addEventListener("push", (event) => {
console.log("[serviceWorker] Push message received", event);
event.waitUntil(
idbKeyval.get('fetchNotificationDataUrl')
.then(url => {
console.log("[serviceWorker] Fetching notification data from -> " + url);
return fetch(url, {
credentials: "include"
});
})
.then(response => {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log("[serviceWorker] Looks like there was a problem. Status Code: " + response.status);
throw new Error();
}
// Examine the text in the response
return response.json();
})
.then(data => {
if (!data) {
console.error("[serviceWorker] The API returned no data. Showing default notification", data);
//throw new Error();
showDefaultNotification({ url: "/" });
}
notifyClientToPlaySound(); <------ HERE
var title = data.Title;
var message = data.Message;
var icon = data.Icon;
var tag = data.Tag;
var url = data.Url;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: tag,
data: {
url: url
},
requireInteraction: true
});
})
.catch(error => {
console.error("[serviceWorker] Unable to retrieve data", error);
var title = "An error occurred";
var message = "We were unable to get the information for this push message";
var icon = "/favicon.ico";
var tag = "notification-error";
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: tag,
data: {
url: "/"
},
requireInteraction: true
});
})
);
});
但是当调用 clients.openWindow 时,它会返回以下异常:
Uncaught(在promise中)DOMException:不允许打开窗口。
我该如何解决这个问题?
答案 0 :(得分:2)
Web Notifications API的实时规范确实引用了在显示通知时可以指定的sound
property,理论上允许您在显示服务工作者的通知时播放您选择的声音。< / p>
但是,虽然规范引用了此属性,截至撰写本文时,it's not supported in any browsers。
您最好的选择是post a message一个由当前服务工作人员控制的打开窗口,并让窗口播放声音以响应message
事件。
如果没有可用的受控客户端(例如,因为您的服务工作人员被push
事件唤醒,并且您的网站目前尚未在浏览器中打开)那么您就拥有了notificationclick
处理程序中opening a new window的选项,该响应是在用户点击您在push
事件处理程序中显示的通知时触发的。然后,您可以将消息发布到该新窗口。