如何在没有后端服务器的情况下 24 小时后触发桌面通知?

How to trigger desktop notification 24 hours later without backend server?

假设:

  1. 用户允许在我的网站上发送通知。
  2. Service Worker 已安装并准备就绪。
  3. 用户设置客户端提醒,从现在起 24 小时提醒。
  4. 没有后端服务或服务器可将通知推送给用户。

如果没有后端服务器推送通知,如何触发桌面通知?这可能吗?

如果提供 timeout/interval 并且 web-alarm/task-scheduler specification 尚未准备好使用,则服务工作者将被浏览器关闭。是否没有仅客户端的方法可以在将来的某个指定时间触发通知?

是否有严格意义上不是 "push notification" 的桌面通知?推送通知本质上是从服务器推送的。是否可以从客户端触发通知?

我认为目前这不可能。

推送通知在 RFC8030 中指定,来自其摘要:

This document describes a simple protocol for the delivery of real-
time events to user agents. This scheme uses HTTP/2 server push.

这意味着需要服务器支持 HTTP/2 推送。

我很喜欢在 Javascript 上大喊大叫,而且我似乎无法在浏览器中找到 Javascript 到 运行 的 HTTP2 服务器的实现(有对于节点),这对我来说是一种耻辱,并且嘲笑它会很棒。

所以,求名利,http2-server.js不见了

您或许可以考虑使用 localStorage。但是,这仅对使用相同设备和浏览器的用户有益。

下面是一个在页面加载时启动的函数。如果您希望它在整个会话期间定期发生,您可以将其包装到 setInterval 中并定期检查。这是假设它需要精确到毫秒后 24 小时。

// on page load
window.onload = () => {
    const dayMs = 24*60*60*1000; // 1 day in milliseconds
    const notificationTimer = localStorage.getItem('notificationTimer');
    if(notificationTimer){
        const sendNotification = (Date.now() - (new Date(notificationTimer)).getTime()) > dayMs;
        if(sendNotification){
            const notification = new Notification('Displaying next day reminder from yesterday');
        }
    }

};

当用户选择第二天提醒时你可以再设置notificationTimer:

localStorage.setItem(notificationTimer, Date.now());

您必须对无法跨浏览器或设备工作的第二天提醒做出一些警告,这可能是可取的,也可能不是可取的。

写这篇文章时的情况(2019 年 1 月 3 日):

There is no "desktop notification" that is not strictly "push notification" and works well cross platforms.

  • 如果您的应用程序不在后台运行,则无法触发 "desktop notification"。
  • Service Worker 不应该使用定时器,并且会被关闭。
  • 操作系统或其他实用软件也可能会建议甚至关闭您的后台应用程序。
  • 没有仅客户端的方法可以在将来的精确时间触发您的通知。目前组织不允许这种情况发生的原因太多了。

您唯一的选择似乎是使用不同的推送通知服务以及外部计划服务,该服务将根据自定义计划触发外部通知。

Your requirements as I understand them:

  • 每个访问者都需要订阅推送通知
  • 记录外部客户偏好(例如:使用一些云调度)
  • 使用外部调度服务触发推送通知服务。

PUSH NOTIFICATIONS are SERVER TRIGGERED not CLIENT REQUESTED

推送通知的要点是您应该从外部触发通知,以避免使用最终用户设备上的资源。这不会阻止您收集用户的通知首选项,将此信息保存在外部,以便您可以在需要时从外部触发通知。

有关 PWA 通知的详细信息,请参阅以下文章: https://developers.google.com/web/fundamentals/codelabs/push-notifications/

据我所知,PWA Service Worker 不应该使用计时器!

作为使用 PWA 通知的替代方法,您可能需要考虑使用不同的通知服务。例如FCMhttps://firebase.google.com/docs/cloud-messaging/

想法可能是在外部保存用户的通知首选项,并在到达预定时间时通过另一个云服务触发 FCM 通知。

显然,这些通知只有在用户连接到网络时才会起作用。然而,任何需要网络访问的通知服务也会出现这种情况。

希望以上内容对您有所帮助,干杯,编码愉快!

假设您网站上的通知数据不会从服务器发送。使用本地存储将是可行的方法。

您可以存储一个变量来帮助跟踪何时在用户访问您的网站时显示通知:

localStorage.setItem("lastNotification", Date.now());

所以你可以有一个执行以下操作的脚本;

function notificationHelper(){
    var lastTime = localStorage.getItem("lastNotification");
    if(Date.now - lastTime > 86400000){

        //Logic to show notication here
        //set a new time at the end of the logic

    }
    //Otherwise Do Nothing
}