一、Chrome浏览器音/视频无法自动播放第一种修改chrome 浏览器配置添加对应的网站地址或者html 代码允许其播放声音。二、Chrome桌面提醒功能兼容新老版本firefox最新版本也通过!DOCTYPE html html langen head title new document /title meta charsetutf-8 meta http-equivX-UA-Compatible contentIEedge,chrome1 meta namerenderer contentwebkit meta nameviewport contentwidthdevice-width, initial-scale1, maximum-scale1, user-scalableno /head body div button typebutton autofocus onclickstart()测试发送消息/button /div script function start(){ var count1 setInterval((){ notify(测试,测试count) count },1000) } //桌面提醒 function notify(title, content) { console.log(notify) if(!title !content){ title 桌面提醒; content 您看到此条信息桌面提醒设置成功; } //var iconUrl /images/send_ok.png; var iconUrlhttps://profile-avatar.csdnimg.cn/764d816f76e346ea98a3a6ffefde8588_simayilong.jpg if (window.webkitNotifications) { //chrome老版本 if (window.webkitNotifications.checkPermission() 0) { var notif window.webkitNotifications.createNotification(iconUrl, title, content); notif.display function() {} notif.onerror function() {} notif.onclose function() {} notif.onclick function() {this.cancel();} notif.replaceId Meteoric; notif.show(); } else { window.webkitNotifications.requestPermission($jy.notify); } } else if(Notification in window){ // 判断是否有权限 if (Notification.permission granted) { var notification new Notification(title, { icon: iconUrl, body: content, }); } //如果没权限则请求权限 else if (Notification.permission ! denied) { Notification.requestPermission(function(permission) { // Whatever the user answers, we make sure we store the // information if (!(permission in Notification)) { Notification.permission permission; } //如果接受请求 if (permission granted) { var notification new Notification(title, { icon: iconUrl, body: content, }); } }); } } } /script /body /htmlrecat 代码### Recat index.tsx /* 1. 进入页面时请求通知权限 2. 建立websocket连接 2.1 收到来自后端的消息更新页面数据 2.2 如果是页面被隐藏那么则进行通知提示 */ import warmTipsAudio from /assets/warmTips.mp3; import type { TableProps } from antd; import { Alert, message, Space, Statistic, Table, Tag } from antd; import { useEffect, useRef, useState } from react; interface DataType { key: string; name: string; age: number; address: string; tags: string[]; } const columns: TablePropsDataType[columns] [ { title: Name, dataIndex: name, key: name, render: (text) a{text}/a, }, { title: Age, dataIndex: age, key: age, }, { title: Address, dataIndex: address, key: address, }, { title: Tags, key: tags, dataIndex: tags, render: (_, { tags }) ( {tags.map((tag) { let color tag.length 5 ? geekblue : green; if (tag loser) { color volcano; } return ( Tag color{color} key{tag} {tag.toUpperCase()} /Tag ); })} / ), }, { title: Action, key: action, render: (_, record) ( Space sizemiddle aInvite {record.name}/a aDelete/a /Space ), }, ]; export default function Warning() { const [sum, setSum] useState(0); const [tableData, setTableData] useStateDataType[]([]); const [notifArr, setNotifArr] useStateNotification[]([]); const [visible, setVisible] useState(false); const [messageApi, contextHolder] message.useMessage(); // 这个值要取localStorage的notifyTip const [notifyTip, setNotifyTip] useState(true); // 这个值存到浏览器中 const [warmTips, setWarnTips] useState(true); // 音频控制 const warmTipsAudioRef useRef(); const handleWarmTipsClose () { setWarnTips(false); localStorage.setItem(warmTips, false); }; const closeNotif () { if (document.visibilityState visible) { notifArr.forEach((item: Notification) { item.close(); }); setNotifArr([]); } }; const handleNotifyTip (e: boolean) { setNotifyTip(e); localStorage.setItem(notifyTip, e ); }; const initNotifyPermission () { const notify new Notification(提示3s后自动关闭, { body: 当弹窗被遮挡或是收起的时候会通过此形式将「预警信息」提示用户, icon: https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png, }); handleNotifyTip(false); setTimeout(() { notify.close(); }, 3000); }; // 请求用户通知权限需要用户点击允许 const notificationSet () { if (!(Notification in window)) { // 检查浏览器是否支持通知 setVisible(true); } else if (Notification.permission granted) { // 检查是否已授予通知权限如果是的话创建一个通知 initNotifyPermission(); } else if (Notification.permission default) { // 默认则征求用户的许可 Notification.requestPermission().then((permission) { // 如果用户接受我们就创建一个通知 if (permission granted) { initNotifyPermission(); } else { // 用户点击拒绝再次发起征求请求 setNotifyTip(true); messageApi.open({ type: error, content: 您禁用了该页面发出通知这将导致您收不到后续更新提示请在浏览器设置中放开该页面通知权限, duration: 10, }); } }); } else { // 提示用户放开浏览器通知权限和系统通知权限 setNotifyTip(true); handleNotifyTip(true); } }; // 建立websocket连接 const webSocketSet () { // Create WebSocket connection. const socket new WebSocket(ws://localhost:8080); // 监听连接 socket.addEventListener(open, function () { socket.send(Hello Server!); }); // 监听后端传来的消息 socket.addEventListener(message, function (event) { console.log(Message from server , event.data); // 用新增一行table来标识接受到了消息 setTableData((data) [ ...data, { key: Math.random().toString(36).slice(-6), name: Joe Black, age: 32, address: Sydney No. 1 Lake Park, tags: [cool, teacher], }, ]); // eslint-disable-next-line no-param-reassign setSum((sum) sum 1); // 同时在这里判断若网页变为不可见了则进行提示 if (document.visibilityState ! visible) { // 通知被关闭再发不要一直发 const notif new Notification(数据已更新请立即查看, { body: 具体信息。。。, icon: https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png, requireInteraction: true, image: https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png, }); notif.onclick () { window.focus(); }; warmTipsAudioRef.current.play(); setNotifArr((data: Notification[]) [...data, notif]); } }); }; useEffect(() { notificationSet(); webSocketSet(); if (localStorage.getItem(warmTips)) { setWarnTips(localStorage.getItem(warmTips) true ? true : false); } if (localStorage.getItem(notifyTip)) { setNotifyTip(localStorage.getItem(notifyTip) true ? true : false); } }, []); useEffect(() { document.addEventListener(visibilitychange, closeNotif); return () { document.removeEventListener(visibilitychange, closeNotif); }; }, [notifArr]); return ( {contextHolder} {warmTips ( Alert message若您收不到该页面发出的通知可能是您禁止该页面发出通知或者是该浏览器被系统禁止发出通知请放开相关权限 typeinfo showIcon closable style{{ marginBottom: 10px }} onClose{handleWarmTipsClose} / )} {notifyTip ( Alert message该页面已被禁止发出通知这将导致您收不到后续更新提示请检查 typeerror showIcon closable / )} {visible ( Alert message该浏览器不支持通知 typeerror showIcon closable / )} Statistic title数据量 value{sum} / Table columns{columns} dataSource{tableData} / audio src{warmTipsAudio} style{{ display: none }} ref{warmTipsAudioRef} /audio / ); } ### websocket server nodejs const express require(express); const WebSocket require(ws); const WebSocketServer WebSocket.WebSocketServer; const app express(); app.get(/, (req, res) { res.send({ ok: 1, }); }); app.listen(3000, () { console.log(express start); }); const wss new WebSocketServer({port: 8080}); wss.on(connection, function connection(ws) { ws.on(error, console.error); ws.on(message, function message(data) { console.log(received: %s, data); }); setInterval(() { ws.send(something, {binary: false}); }, 4000); });这里还有一个额外的知识就是我发现某些网页能够实现即使浏览器没有打开也可以发送通知的功能这个我去了解了一下大致原理如下有需要的朋友自行阅读「即使浏览器未打开某些网页也能发出桌面通知」通常是通过浏览器推送通知Browser Push Notifications技术实现的。具体来说这项功能依赖于以下几个关键技术组件服务工作线程Service Workers服务工作线程是一种独立于网页主线程的脚本能够在后台运行即使浏览器未打开或者用户没有打开特定网站。它们在浏览器中作为一个中间层处理网络请求、推送通知、缓存等任务。服务工作线程可以在后台保持活跃并在接收到来自服务器的推送消息时触发通知。推送通知Push Notifications推送通知是由服务工作线程处理的消息。这些通知通过推送服务从服务器发送到用户的浏览器即使用户当前没有访问该网站。推送服务将消息传递到浏览器中的服务工作线程后者可以根据消息的内容在桌面上显示通知。Web 推送 APIWeb Push API这是一个标准化的 API允许网站在用户授权后注册一个服务工作线程并通过推送服务发送通知。网站首先需要获得用户的许可才能使用这项功能。一旦用户同意网站可以在服务工作线程中注册推送事件并配置通知的内容。浏览器推送服务Browser Push Service各大浏览器都有自己的推送服务用于中转来自网站的推送消息。这些服务确保消息能够在合适的时间传递给浏览器即使用户未打开浏览器。这些推送服务通常与操作系统通知系统集成确保通知能在桌面上显示。工作流程概述用户授权当用户访问支持推送通知的网站时网站会请求通知权限。服务工作线程注册如果用户同意浏览器会在后台注册一个服务工作线程。推送通知网站服务器通过浏览器的推送服务向用户的设备发送通知即使浏览器未打开服务工作线程也能接收到这些消息并在桌面上显示通知。这种机制使得网站能够在用户没有主动访问时仍然与用户保持互动提供及时的信息或提醒。