移动版Chrome浏览器中HTML5通知无法工作

51

我正在使用HTML5通知API在Chrome或Firefox中通知用户。在桌面浏览器中,它可以正常工作。然而,在Android的Chrome 42中,虽然请求权限成功,但通知本身没有显示。

这个请求代码可以在所有设备上工作:

if ('Notification' in window) {
  Notification.requestPermission();
}

发送邮件的代码在桌面浏览器上可以工作,但在移动设备上却无法工作:

if ('Notification' in window) {
  new Notification('Notify you');
}

2
我遇到了完全相同的问题。我也尝试了 window.webkitNotification。另一方面,推送通知可以工作,但是它们是完全不同的东西:https://developers.google.com/web/updates/2015/03/push-notificatons-on-the-open-web?hl=en (演示 https://simple-push-demo.appspot.com/) - BoppreH
5个回答

72

请尝试以下方法:

navigator.serviceWorker.register('sw.js');
Notification.requestPermission(function(result) {
  if (result === 'granted') {
    navigator.serviceWorker.ready.then(function(registration) {
      registration.showNotification('Notification with ServiceWorker');
    });
  }
});

也就是说,使用ServiceWorkerRegistration»showNotification()而不是new Notification()

这在Android上的Chrome和Firefox中都应该可以工作——在iOS的Safari上也一样。

(sw.js文件可以只是一个零字节的文件。)

需要注意的是,你必须从安全来源运行它(一个https URL,而不是http URL)。

请参阅https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/showNotification


3
这个方法可行,但需要创建一个具有自己生命周期的后台ServiceWorker。我希望能有一种更轻量级的解决方案,但也无妨。感谢你详尽的回答。 - BoppreH
3
关于寻找一种更轻量级的解决方案(不需要使用 ServiceWorker),我建议花时间在 https://github.com/whatwg/notifications/issues 上提出问题。这些人非常想要来自现实世界中的 Web 开发者的反馈,而根据我的经验,他们对获取的反馈非常积极响应。但是如果没有人发送反馈,那么改变的可能性就会小得多。 - sideshowbarker
5
建议的解决方案无法处理点击事件,这可能是为什么Android中没有提供轻量级API的同样原因。由于页面可能会被内存管理器随时终止,所以不能保证通知被点击时页面会存在,这会导致API非常不稳定。 - Miguel Garcia
你好,我一直收到这个错误信息:“failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR”,而且套接字对象的创建显示为错误源头 [websocket = new WebSocket("wss://www2.demo.domainname.com:45786/directory/socket.php");]。 45786是我在非SSL版本中使用的端口号,它正常工作。 用443替换它或完全去掉都没有用。请问您有任何建议可以修复吗? - Ashil John
2
我在哪里可以获取sw.js文件? - Encrypted
@Encrypted,你可以在谷歌上搜索 firebase-messaging-sw.js CDN。 - Wibisono Indrawan

6
如果您已经注册了一个服务工作者,请使用以下内容:
navigator.serviceWorker.getRegistrations().then(function(registrations) {
  registrations[0].showNotification(title, options);
});

4
运行以下代码:
 if ('Notification' in window) {
  Notification.requestPermission();
}

在Chrome DevTools的控制台中显示以下错误:

Uncaught TypeError: Failed to construct ‘Notification’: Illegal constructor. Use ServiceWorkerRegistration.showNotification() instead

更好的解决方法可能是:

function isNewNotificationSupported() {  
    if (!window.Notification || !Notification.requestPermission)  
        return false;  
    if (Notification.permission == 'granted')  
        throw new Error('You must only call this \*before\* calling 
Notification.requestPermission(), otherwise this feature detect would bug the 
user with an actual notification!');  
    try {  
        new Notification('');  
    } catch (e) {  
        if (e.name == 'TypeError')  
            return false;  
    }  
    return true;  
}

功能来源:HTML5Rocks


很遗憾,似乎无法在不显示弹出窗口的情况下测试新通知。 - Pieter De Bie

3
我在Windows桌面上使用Notification API没有遇到任何问题。在移动FF上也能无障碍运行。我找到的文档似乎表明Chrome for Android也受支持,但它在我的设备上无法正常工作。我真的很想证明API 在我目前使用的 Chrome (70) for Android 上可以工作。经过多次调查,我可以轻松地看出为什么许多人的结果是混合的。当我将上面的答案粘贴到一个简单的页面中时,它对我来说根本不起作用,但我发现了原因。根据Chrome调试器显示,Notification API 仅在响应用户手势时才被允许使用。这意味着您不能在文档加载时简单地调用通知。相反,您必须在响应像点击之类的用户交互性事件中调用代码。
因此,以下是一个简单而完整的解决方案,证明您可以在当前(2019)的Chrome for Android上使通知工作(注意:我仅使用jQuery是为了简洁)。
<html>

<head>
<script type="text/javascript" src="libs/jquery/jquery-1.12.4.min.js"></script>
<script>

$( function()
{
    navigator.serviceWorker.register('sw.js');

    $( "#mynotify" ).click( function()
    {
        Notification.requestPermission().then( function( permission )
        {
            if ( permission != "granted" )
            {
                alert( "Notification failed!" );
                return;
            }

            navigator.serviceWorker.ready.then( function( registration )
            {
                registration.showNotification( "Hello world", { body:"Here is the body!" } );
            } );

        } );
    } );
} );

</script>

</head>

<body>
<input id="mynotify" type="button" value="Trigger Notification" />
</body>

</html>

总结一下,关于当前(2019年)Chrome for Android上的通知,需要了解以下重要事项:

  1. 必须使用HTTPS
  2. 必须在用户交互响应中使用Notification API
  3. 必须使用Notification API请求通知权限
  4. 必须使用ServiceWorker API触发实际通知

有没有一种方法可以使用服务工作者检查现有的权限?类似于 if (Notification.permission === "granted") {...} - Roy Prins
1
实际上,您可以像您描述的那样使用通知API来检查现有权限。Chrome for Android的独特之处在于,通知API目前无法用于创建实际的通知。但是,它确实可以用于检查权限和请求权限。一旦获得了权限,您就可以使用ServiceWorker API来实际显示通知。 - Jeff Bruce
1
对我没有用。@Ben的答案使用registrations[0]有效。 - user66081
1
在我的Ubuntu桌面版Chrome浏览器和Android设备上都无法工作。 - gene

2

new Notification('your arguments');
这种方式创建通知只在桌面浏览器上支持,手机浏览器不支持。请参考下面的链接(向下滚动到兼容性部分):
https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API

对于手机浏览器,您可以使用以下方式创建通知(在桌面浏览器上也适用):

navigator.serviceWorker.ready.then( reg => { reg.showNotification("your arguments goes here")});

已在使用webkit引擎的浏览器上进行测试。

有关更多信息,请访问以下链接:
https://developers.google.com/web/updates/2015/05/notifying-you-of-changes-to-notifications https://developers.google.com/web/fundamentals/push-notifications/display-a-notification


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接