Web Notification API实战:从权限申请到Service Worker消息推送
我们做前端经常会收到产品需求“用户下单后要发个通知”、“有站内消息时浏览器最好弹一下”。以前一提到通知第一反应就是短信、邮件、推送SDK其实浏览器本身就支持一套原生的通知能力利用好它很多轻量级提醒需求完全不需要引入第三方服务。这套能力就是 Web Notification API配合 Service Worker 还能实现消息推送的离线提醒。这篇文章我会从零开始把浏览器通知功能的原理、权限申请、基础弹窗、事件处理、定时轮询、消息队列、兼容性问题这些全部过一遍全部是项目里实测过的方案和踩坑记录适合正在做前端开发的工程师或者对网页交互体验有要求的全栈同学参考。1. 浏览器通知功能概览与原理1.1 什么是 Web Notification API很多人分不清“浏览器通知”和“Web Push 推送”。简单说浏览器通知就是页面里通过Notification构造函数创建的一个系统级弹窗它不属于页面 DOM而是操作系统原生绘制的一个消息条。用户即使切到其他标签页或者把浏览器最小化只要浏览器进程还在运行通知就有机会弹出来。这套 API 非常独立你不需要注册任何第三方账号打开任意一个 HTTPS 页面申请权限后就能用。核心调用就几行if (Notification in window) { Notification.requestPermission().then(permission { if (permission granted) { new Notification(你好, { body: 这是一条测试通知 }); } }); }这是最简单的用法但真实项目里只做到这一步肯定不够。生产环境要考虑通知点击跳转、重复通知过滤、通知关闭后的统计、和后台任务的协同这些是我后面要重点讲的。1.2 权限模型与浏览器差异通知权限遵循“用户代理”的权限模型也就是说权限是“站点 浏览器”维度而不是“用户 页面”维度。同一个用户访问你的站点在 Chrome 里授权了不等于在 Firefox 里也授权了。同一个浏览器里访问不同二级域名权限通常也不互通。权限状态一共有三种default未询问、granted允许、denied拒绝。这里有一个容易踩的坑default状态看起来是“未决定”但一旦用户点了浏览器的地址栏前的图标手动改成了阻止那么浏览器内部的权限状态其实变成了denied但页面上用Notification.permission读到的值有可能仍然是default。这个问题在旧版 Chrome 里出现过现在虽然修了但要提醒一句不要拿Notification.permission default作为“可以再次弹权限请求”的唯一判断依据最好结合permissions.query({ name: notifications })来查。桌面端的 Safari 早期只支持 callback 风格不支持 Promise代码要做兼容。移动端 Chrome 对 Notification 的支持也有版本差异。这些细节我放到第 4 节单独讲。2. 基础实现从申请权限到弹出一条通知2.1 申请权限的正确姿势权限请求不能乱弹这是很多产品经理不理解、前端需要把关的地方。浏览器对权限请求有“信任阈值”一说——如果用户刚打开页面就强制弹权限拒绝率超过 80%。正确做法是把权限请求绑定在一个用户明确想要接收消息的动作上比如点击“开启消息提醒”按钮或者完成订阅之后。下面是封装好的权限申请函数我把多浏览器差异也处理进去了async function requestNotifyPermission() { // 老版本 Safari 用 callback if (typeof Notification.requestPermission ! function) { return Notification.permission; } // 新标准是 Promise const permission await Notification.requestPermission(); return permission; }注意requestPermission在每次调用时都会返回当前权限状态不一定保证弹窗。如果用户已经是granted直接拿状态返回。如果是denied那就不能再次弹窗。我们可以在 UI 上给用户显示一个“如何在浏览器设置中开启通知”的引导图而不是反复调用。在实际项目里我还会加一个“用户是否曾经拒绝过”的本地标记。用localStorage存一下比如notify_denied1避免刷新页面后又在某个交互动作里反复触发请求。这属于产品层面的保护但对用户体验影响非常大。2.2 创建通知与参数详解真正的业务通知不会只有一句话我们需要构造更丰富的通知内容。Notification构造函数接受两个参数title和options。options里值得关注的字段如下body正文内容最多显示两行超出部分会省略。icon通知条左侧的图标建议使用 192x192 以上的图片。badge在部分系统如 Android Chrome 上显示的小徽标建议是灰度透明 PNG。image稍大尺寸的展示图目前 iOS Safari 不支持。tag通知分组标记。同一个tag的新通知会替换旧通知不产生堆积。data附加任意数据点击通知时可以通过事件读取。requireInteraction布尔值设为true表示通知常驻不自动消失。但用户要手动关闭容易打扰人。actions通知上可以附带一些按钮操作如“查看”“忽略”目前移动端 Safari 不支持。一个实用的通知示例function showNotification({ title, body, url, tag }) { if (Notification.permission ! granted) return; const notify new Notification(title, { body, tag: tag || default-tag, icon: /static/img/logo-192.png, badge: /static/img/badge.png, data: { url: url || location.href }, requireInteraction: false, actions: [ { action: open, title: 查看详情 }, { action: later, title: 稍后处理 } ] }); return notify; }这里留意tag字段的意义。有些需求是“每一笔订单都要弹一次通知”那就不要设tag或者用不同tag。如果需求是“同一个会话内只显示最新的一条”就固定用一个tag。用错tag会导致通知被覆盖看起来像是“漏通知”了。2.3 事件处理与通知交互通知不是弹出来就完事了。用户点击通知、关闭通知后端很可能都需要记录。比如点击通知后要跳转到对应页面关闭通知后要停止声音播放或取消角标。这些都要通过事件监听来做。Notification实例上主要有四个事件show、click、close、error。const notify showNotification({ ... }); if (notify) { notify.addEventListener(click, (event) { event.preventDefault(); const { url } event.currentTarget.data; window.open(url, _blank); notify.close(); }); notify.addEventListener(close, () { // 通知关闭可以做埋点 trackNotifyClose(manual_close); }); notify.addEventListener(error, (err) { console.error(通知展示失败, err); }); }有一个坑在用户点击通知时浏览器会自动聚焦到当前页面并触发window.focus。如果你希望点击通知后新建标签页而不是替换当前页面记得在 click 处理函数里先preventDefault()再window.open。另外部分浏览器在通知关闭后close事件并不会在所有场景下都触发比如通过requireInteraction: true的通知用户点了系统层的“关闭”按钮close事件可能不会被触发。所以不要依赖这个事件做关键业务逻辑只能做辅助统计。3. 进阶实战定时通知与消息队列管理3.1 通过 Service Worker 实现离线通知页面必须处于打开状态才能用Notification吗不是的。借助 Service Worker 的showNotification()方法即使页面已经关闭只要浏览器后台还有 Service Worker 在运行仍然可以弹通知。前提是用户已经授予通知权限并且你注册了 Service Worker。Service Worker 可以在自己的sw.js里响应推送事件。如果是自定义的定时提醒我们常常在页面里向 Service Worker 发消息让后台去定时触发。先注册 SWif (serviceWorker in navigator) { navigator.serviceWorker.register(/sw.js).then((registration) { console.log(SW registered, registration.scope); }); }然后页面里给 SW 发消息navigator.serviceWorker.ready.then(registration { registration.showNotification(后台提醒, { body: 这是一个由 Service Worker 弹出的通知, icon: /static/img/logo-192.png, data: { url: /detail.html?id123 } }); });区别在于普通new Notification()只能在前台页面使用而 Service Worker 的showNotification()可以在后台调用。但普通页面里也需要用registration.showNotification()吗不强制。不过为了让代码统一我建议页面侧也尽量通过 SW 来弹通知因为后续如果要换成 Push API逻辑迁移成本会低很多。3.2 定时触发与逻辑设计“定时通知”最常见的问题是浏览器限制后台定时器的执行频率。如果你在页面里用setTimeout设置了一分钟后弹通知然后用户把页面挂起或者浏览器进入省电模式定时器可能会被冻结。语音唤醒或时间到了不弹就是这种情况。可靠做法是把定时任务放到 Service Worker 里。虽然 SW 也不是完全意义上的后台守护进程但它的生命周期比页面稳定很多。浏览器允许 SW 在注册后持续运行一小段时间并且在检测到事件比如notificationclick后被唤醒。如果只是纯粹“延时弹通知”可以用setTimeout写在 SW 里但不保证长时间断网或关机后仍能触发。如果需求是需要精确到秒级同时需要服务端参与那推荐方案是 Web Push 协议服务器控制推送时机浏览器收到推送后触发push事件。但 Web Push 需要 VAPID 密钥依赖额外后端这里不详细展开。下面我给出一个真实的项目示例用户设置“每30分钟提醒一次喝水”。我把这个需求拆成两部分服务端生成下一次提醒的时间戳并返回给前端前端在 localStorage 中存储这个时间戳然后在页面可见且定时器可用时用setInterval检查到点后调用 SW 弹通知。同时在页面隐藏时尽量依赖 SW 内部定时器。// 页面脚本 function scheduleWaterReminder(nextTs) { localStorage.setItem(waterNextTs, nextTs); const remain Math.max(0, nextTs - Date.now()); setTimeout(() { navigator.serviceWorker.ready.then(reg { reg.showNotification(喝水提醒, { body: 已经工作半小时了起来动一动吧。, tag: water }); }); }, remain); }这样的实现有一个不可避免的缺点如果用户把整个浏览器完全关掉那么定时通知肯定不会触发。目前纯粹的前端技术解决不了这个问题需要后端配合 Web Push。所以接到需求时第一件要和产品确认的事就是允许的最小触发精度和浏览器关闭场景下的要求是什么。3.3 多通知管理与用户配置通知一多就需要管理。用户可能今天不想收促销通知明天又想开了。你可以提供一个简单的设置面板把通知权限申请、全局开关、细分类型开关都放进去。我推荐用这三个字段控制通知展示notifyEnabled总开关默认 false用户手动开启。notifyTypes一个对象如{ order: true, message: true, promotion: false }。notifyTimes静默时段比如每天 22:00 到次日 8:00 不弹。展示逻辑放在一个统一的shouldNotify(type)函数里function shouldNotify(type) { if (!localStorage.getItem(notifyEnabled)) return false; const types JSON.parse(localStorage.getItem(notifyTypes) || {}); if (!types[type]) return false; const now new Date(); const hour now.getHours(); if (hour 22 || hour 8) return false; return Notification.permission granted; }当总开关为关闭时即使之前已经申请过权限也不要弹通知。因为用户关闭开关的意图是“暂时不想被打扰”而浏览器权限仍然有效。这里要注意Notification.permission只能表示权限是否允许不能表达“用户当前是否愿意接收某类内容”。这两者一定要分开存。多通知管理还有一个细节相同tag的通知会互斥更新。对消息中心这种场景如果你希望每条消息都独立展示就不要设tag。如果希望同类型只保留最后一条就固定tag。通知的tag值还可以控制关闭例如点击“查看全部”时把所有tag为message的通知全部关闭避免用户逐条关闭。4. 兼容性、常见坑与性能优化4.1 浏览器兼容性速查前端做任何功能都得先看兼容性。我整理了一份实战笔记基于近两年的主流浏览器版本浏览器Notification APIService Worker showNotification点击事件通知按钮 actionsChrome 桌面支持支持支持支持Edge 桌面支持支持支持支持Firefox 桌面支持支持支持支持Safari 桌面支持callback 风格部分支持新版支持支持不支持iOS Safari14.5 支持需要添加主屏幕14.5 受限支持支持不支持Android Chrome支持支持支持支持如果目标用户中有大量 iOS Safari不要指望actions能正常显示。在 iOS 上通知展示策略也有差异如果是普通网页添加了主屏幕通知行为会好一些直接用浏览器访问的页面通知条只展示在锁屏或企业证书环境下有限支持。做兼容性判断时不能只用Notification in window来检测因为 Service Worker 环境下并没有window。需要这样封装function isNotifySupported() { return typeof Notification ! undefined || typeof self ! undefined Notification in self; }在 SW 内部self.Notification和self.registration.showNotification可以配合使用。4.2 权限策略与移动端注意事项移动端的权限弹窗和桌面端不一样。Android Chrome 会直接弹系统授权框iOS Safari 只有把网页添加到主屏幕时才能较好地支持通知普通浏览器标签页内调用requestPermission在部分版本上会直接返回denied或静默失败。所以一个很现实的问题是移动端网页如果要玩通知最好引导用户“添加到主屏幕”否则体验天然受限。权限策略上还有一点Notification.requestPermission()只能由用户手势触发。如果你在页面加载后立刻异步调用浏览器会判定为“非用户手势”往往直接拒绝或者不展示授权框。用户手势包括 click、keydown 等不包括移动端的 touch 在部分浏览器上的默认事件所以最好绑定在click上。有个场景我遇到过用户在 iOS Safari 点击“开启通知”按钮页面跳到系统设置询问这个时候 App 会进入后台从系统设置返回页面时Notification.permission已经更新成granted了。这时候不要再调requestPermission直接读取即可。JavaScript 异步流程要考虑到这种中断情况可以在visibilitychange事件里做一次检查避免页面卡在 loading。4.3 常见问题排查下面我把实战中最常遇到的 7 个问题整理成速查表每个都是调试到崩溃才总结出来的现象可能原因解决方案点击“开启通知”后无反应页面不是 HTTPS 或 localhost检查站点协议非安全上下文无法使用权限弹窗没有出现浏览器限制自动弹窗或之前已选择过将权限申请绑定在按钮 click 事件上通知弹出来又立刻消失系统通知设置短自动销毁时间设置requireInteraction: true或者提醒用户调整系统设置通知无法点击跳转没有监听 click 事件或未调用 preventDefault给通知绑定 click 并处理 url删除 tag 相同的通知后新通知不显示相同 tag 的通知会覆盖旧通知换成不同的 tag 或移除 tagService Worker 弹通知失败未注册 SW或者注册响应比通知晚用navigator.serviceWorker.ready等待开发环境点击通知后打开到了不正确页面data.url使用了相对路径解析基准错误在通知的 data 中存储完整绝对 URL还有一个小坑new Notification()在部分浏览器尤其是老版本 Chrome中如果icon指向的图片无法加载会抛出异常。解决方法是提前 catchtry { const notify new Notification(标题, { icon: /bad.png }); } catch (e) { console.warn(通知创建失败, e); }当然最合理的是在创建前用图片预加载或直接校验图片地址可访问性。4.4 性能与用户体验优化通知功能虽然轻量但也会带来性能问题。主要集中在连续弹通知、图片加载、事件回调泄漏三个方面。连续弹通知会导致通知中心堆积用户会烦。合理的策略是合并比如三分钟内有 5 条站内信不要每条都弹而是弹一条“你有 5 条新消息”。这道逻辑简单粗暴地把同一tag的通知刷新为最新内容// 同一 tag 下通知会覆盖旧通知 function notifyWithMerge(title, body, tag, url) { navigator.serviceWorker.ready.then(reg { reg.showNotification(title, { body, tag, data: { url } }); }); }如果有不同 tag要自己做一个合并控制器先把通知存到内存队列如果两秒内还有新的通知就延迟展示最后一条并增加计数。这个方案我在这里提供一个伪代码思路let notifyQueue []; let timer null; function queueNotify(title, body, tag, url) { notifyQueue.push({ title, body, tag, url }); if (timer) return; timer setTimeout(() { const latest notifyQueue[notifyQueue.length - 1]; const count notifyQueue.length; // 若只有一条正常显示多条则显示合并文案 const finalBody count 1 ? 你收到 ${count} 条新消息 : body; navigator.serviceWorker.ready.then(reg { reg.showNotification(finalTitle, { body: finalBody, tag: latest.tag, data: { url: latest.url } }); }); notifyQueue []; timer null; }, 2000); }图片加载是另一个隐性问题。通知里引用的图片如果通过 HTTP 加载在某些浏览器上会被拦截因为通知 API 要求安全资源。建议所有图片都走 CDN 且为 HTTPS。图片尺寸不要超过 Chrome 限制的 512x512 或 4KB 体积不同版本限制不同否则加载失败或失真。可以在构建时用工具将大图压成适合通知展示的尺寸。关于事件回调泄漏每弹一条通知如果都给它绑一个 click 事件旧通知关闭时如果忘记移除监听器虽然浏览器会回收但在长时间运行的单页应用里还是建议统一由onnotificationclick全局处理而不是每条通知单独绑定。SW 里用全局监听self.addEventListener(notificationclick, (event) { const url event.notification.data.url; event.notification.close(); event.waitUntil( clients.matchAll({ type: window, includeUncontrolled: true }).then((clientList) { for (const client of clientList) { if (client.url url focus in client) { return client.focus(); } } return clients.openWindow(url); }) ); });这种方式避免了对每个Notification实例的重复绑定代码也更干净。还有一个很少人提但很重要的体验点通知内容中的title和body长度。Chrome 桌面端在标题超过 20 到 40 个字符时会截断正文超过两行也会省略。所以产品文案要自己控制在有效长度内不要依赖缩略。更不要把关键信息比如验证码放在正文末尾一定会被截断。5. 从 demo 到生产我实际接入后的一些体会做通知功能最容易被低估的是权限和用户预期管理。我见过不少项目上线一周后发现转化率低原因就是第一次访问就弹权限用户被吓跑。正确的姿势应该是先埋一个“引导气泡”解释通知会带来什么等用户点击了按钮再申请权限。这不仅是交互设计更是前端工程里要求我们为产品决策把关。还有一个体会调试通知功能时最好准备两台设备。一台桌面 Chrome一台 Android 真机因为 iOS Safari 的权限坑实在太多。测试的时候要在浏览器设置里重置站点权限否则改完代码再测试权限状态永远是旧的你根本不知道代码哪里出问题。最后再说一个小技巧把通知触发逻辑从 UI 里解耦出来做成一个独立模块。我们项目里就把shouldNotify、queueNotify、showNotifyBySW、handleNotificationClick都放在一个notify.js文件里页面组件只调用notifyModule.push({ type: message, ... })。这样后续如果要换成 Web Push只需要替换模块内部实现所有页面都不用动。维护起来轻松很多。通知功能本身不复杂但它牵扯到权限体系、SW 生命周期、系统交互、用户设置这些约定如果散落在各个组件里后期改一个字段名就能引发连环 bug。集中管理才是长期稳定的关键。

相关新闻

CNN卷积神经网络入门:从卷积层、池化到PyTorch实战

CNN卷积神经网络入门:从卷积层、池化到PyTorch实战

1. CNN为什么存在:从一次全连接网络的翻车说起先讲一个我刚开始接触深度学习时的真实经历。当时我拿到一个手写数字识别任务,觉得神经网络这东西不就是一个接一个的全连接层吗?把图片拉平成一维向量,丢进网络里,反正梯…

2026/10/17 15:47:12 阅读更多 →
Agent+RAG+知识图谱:从事实性失真到可靠推理的工程实践

Agent+RAG+知识图谱:从事实性失真到可靠推理的工程实践

简介:这是2025年Packt出版的英文原版PDF,系统讲述如何结合大语言模型(LLMs)、检索增强生成(RAG)与知识图谱(KGs)构建现代AI智能体,适合具备机器学习与自然语言处理基础、…

2026/10/17 15:46:11 阅读更多 →
CobaltStrike 4.8团队服务器部署实战:从JDK配置到Malleable C2调优

CobaltStrike 4.8团队服务器部署实战:从JDK配置到Malleable C2调优

简介:面向授权红队评估与渗透测试人员,这份CobaltStrike 4.8资源包用于在Java 11环境快速搭建其服务端与客户端,可帮助构建多人协作的命令控制通道,适合具备网络协议基础以及Linux、Windows基本操作能力的安全测试场景。资源共12个…

2026/10/17 15:46:11 阅读更多 →

最新新闻

跨平台SSL证书导入脚本:Windows与Linux批量部署指南

跨平台SSL证书导入脚本:Windows与Linux批量部署指南

简介:这份资源提供在Windows与Linux系统中导入SSL证书的自动化脚本,面向需要为Web服务配置HTTPS通信的运维人员与系统管理员。压缩包内共2个文件,分别为Linux平台使用的sh脚本与Windows平台使用的bat脚本,包体仅578B,轻…

2026/10/17 16:31:36 阅读更多 →
viewer.min.js图片查看器集成指南:从初始化到避坑实践

viewer.min.js图片查看器集成指南:从初始化到避坑实践

简介:viewer.min.js 是一款轻量级 JavaScript 图像查看器库,面向需要在前端实现图片缩放、旋转、平移等交互效果的前端开发者。资源包以 viewerjs-main 命名,共包含 177 个文件,整体打包 3.14MB,其中以 121 个 js 文件…

2026/10/17 16:31:36 阅读更多 →
信呼OA系统开源部署指南:中小团队低成本的协同办公方案

信呼OA系统开源部署指南:中小团队低成本的协同办公方案

简介:信呼协同办公OA系统v1.8.6提供了一套开源的企业办公自动化解决方案,适合中小型企业和研发团队使用,能够将流程审批、任务协作、日程管理、移动办公等常见需求整合到一个平台中。这个版本在之前基础上优化了系统稳定性和操作体验&#xf…

2026/10/17 16:31:36 阅读更多 →
Flutter蓝牙开发实战:协议设计、插件选型与跨平台适配

Flutter蓝牙开发实战:协议设计、插件选型与跨平台适配

1. 蓝牙协议在 Flutter 项目中的整体设计思路1.1 为什么要在移动端项目里引入蓝牙能力做移动端项目时间长了,总会碰到一类需求:设备不在云端,也不走 Wi-Fi,而是靠蓝牙近距离通信。比如智能手环同步步数、体脂秤回传数据、便携打印…

2026/10/17 16:31:36 阅读更多 →
油猴脚本从入门到实战:安装配置与高效使用指南

油猴脚本从入门到实战:安装配置与高效使用指南

1. 先搞懂油猴插件到底是什么说到油猴插件,很多人的第一反应是:听说过,但一直没搞懂。以为它是什么灰色地带的黑科技,或者觉得那是程序员才折腾的东西。今天把话说透,油猴插件/脚本就是一个运行在浏览器里的轻量小助手…

2026/10/17 16:31:36 阅读更多 →
TortoiseGit绿色对勾消失?从图标覆盖到注册表抢位的完整排查指南

TortoiseGit绿色对勾消失?从图标覆盖到注册表抢位的完整排查指南

那天我像往常一样打开资源管理器,突然发现整个工作目录的文件夹都变成了最普通的黄色小文件夹——TortoiseGit 的绿色对勾不见了。第一反应是仓库坏了,赶紧打开终端跑了个 git status ,结果文件状态一切正常,也没有任何报错。那…

2026/10/17 16:30:36 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →