大多数浏览器和
Developer App 均支持流媒体播放。
-
Safari 浏览器网页推送功能简介
利用“网页推送”,在 macOS 的 Safari 浏览器中优化您的网站和网页版 App 的通知功能。我们将说明如何通过基于网页标准的 Push API、Notifications API 和服务工作线程组合向用户发送通知。
资源
- Learn more about bug reporting
- Notifications API
- Push API
- Sending web push notifications in web apps and browsers
- Service Worker API
相关视频
WWDC23
WWDC22
-
下载
♪ ♪
Brady Eidson: 大家好 我叫 Brady Eidson 是 WebKit 架构团队的工程师 我很高兴向您介绍 Safari 浏览器中的网页推送功能 网页推送可以让您 给您的网络 App 用户 发送远程通知 这里 在屏幕的右上角 是来自 webkit.org 的通知显示 点击通知打开 新窗口中的 WebKit 博客文章 在我讲述它的工作原理的 其它细节之前 我想回答几个 很多开发者想问的问题
从 macOS Ventura 开始 Mac Safari 浏览器开始支持网页推送 明年 iOS 和 iPadOS 也会安装网页推送
Apple 的 Safari 浏览器推送通知 很久以前就向 接触 Mac Safari 浏览器用户提供了 如今 它还在继续起作用 我很高兴地宣布 我们增加了对网页推送的支持 这是真正的网页推送 各种网络标准的相同组合 也在其它浏览器中使用 我们稍后将讨论这些标准 但是 最重要的是 如果您对您的网络标准 App 进行过编码 就无需在 Safari 浏览器中 对它做任何改变 当然 如果您不用 Safari 浏览器 进行浏览器检测的话 那么您还要做一些其它的工作 现在是浏览器检测到 功能检测的最佳时间 功能检测一直是最佳实践 我们使用的是相同的 Apple 推送通知服务 在所有 Mac 和 iOS 设备上 为本地推送提供动力 但没有 Apple Developer 帐户 需要访问 Safari 浏览器用户 我们正在使用新的 网页推送的端点 URL 它带出另一件事 可能在无意中排除了 Safari 浏览器 如果您在服务器上严密管理推送端点 请确保您允许 URL 来自 push.apple.com 的任何子域 对于那些重要的问题 让我们不但来解答 更要详细地谈一下 首先 我们从用户的角度来看一下 Safari 浏览器中的网页推送体验 然后我们将介绍整个网页推送流程 从请求许可 到在通知中心处理进入许可的点击 最后 我们来看一看 从网页推送 到现有的网络 App 需要添加什么 但首先 我们来看一下 Mac Safari 浏览器用户体验 现场演示一下将是最好的介绍方法 这是 macOS Ventura 上的 Safari 浏览器 在这个浏览器选项卡中 我打开了 webkit.org 我需要用 WebKit 开源项目 保持更新 网页推送是一个很好的方法 如果没有用户请求手势 是不允许使用 webkit.org 请求推送权限的 所以我会在这里 点击这个钟形按钮订阅通知 您在这里看到的是系统通知提示 这与其它 App 是一样的 在这种情况下 它代表 webkit.org 我将单击 allow 一切就绪 webkit.org 给了我选择 收到有关新博客文章的通知 以及对源代码存储库的新的承诺 我知道每次提交都会收到通知 会分散我对重要工作的注意力 但我真的想收到 有关新的博客文章的消息 所以我现在要检查那个框 巧合的是 一定有人刚刚发布了 关于网络推送的 WebKit 博客文章 此通知看起来和任何其它的一样 是由 webkit.org 推送的 我可以点击它来激活 还有博客文章 要在 Safari 浏览器中打开 一旦用户授予网站权限 他们就控制了该许可 作为一个 macOS 用户 我习惯了在系统设置里面 管理通知首选项 那里就是我可以 配置 webkit.org 的通知的地方 同样丰富的配置 正如我在 任何其他 App 或服务中所发现的那样 作为 Safari 浏览器用户 我习惯于从 Safari 浏览器偏好设置中 管理网站设置 我也可以去那里打开或关闭 webkit.org 的权限 这就是网页推送的工作原理 适用于 Mac Safari 浏览器中的用户 在我们继续之前 我想重新回复一下 该演示中涵盖的一些内容 首先 我们不希望用户 被没有订阅的垃圾邮件 所打扰 所以一个网站只有在请求的时候 通过点击鼠标或键盘 才会推送订阅 一旦网站获得许可 向用户显示通知 用户就会控制该权限 他们可以选择在 Safari 浏览器的首选项 或系统设置中对它进行管理 如果他们恰巧在两者中 都对它进行管理 设置将保持同步 最后 如果您针对不同类型的事件 提供通知 最好的做法是针对通知类型 在您的网络 App 中 提供精细化控制 就像其他 App 一样 现在您已经看到了 网页推送的实际应用 让我们深入了解一下 每一步正在发生什么 部分开发者已经对此非常熟悉 但是对于那些刚接触网页推送的人来说 我必须一步一步来 向您推荐相关标准和过程中的文档 首先是用户 在浏览器选项卡中访问您的网站 这是在 Safari 浏览器中 打开的 webkit.org 由于它是在选项卡中打开的 它可以安装一个 Service Worker Service Worker 是一个在整个域中 运行的 JavaScript 单元 是从当前打开的浏览器选项卡 一旦 Service Worker 脚本已安装 您的网络 App 就符合了 请求推送订阅的条件 如前所述 此请求必须与用户手势相关联 当点击这个钟形按钮时 webkit.org 请求就会得到许可 这满足了用户手势要求 当您的网站请求推送订阅时 用户就会看到此系统提示 这是他们可以进行 关于授予您的网站这种强大能力的 最终通话的地方
用户可能会拒绝该请求 您的 JavaScript 应该 准备对它进行处理 但假设用户授予了权限 您的 JavaScript 就会回复一个 PushSubscription 对象 里面有您的服务器 给这个浏览器的用户发送推送消息时 所需的一切 像这样的信息 要使用确切的 URL 端点 您可以以任何 适合您的网络 App 的方式 将 PushSubscription 的有效载荷 返回您的服务器 许多流行的服务器包都有 网页推送支持管理订阅 或者您可以自已翻阅 在实际当中这同样适用于如何 以及何时发送推送消息 到您的服务器知道的 URL 端点 我不能告诉您什么时候这样做 这取决于您和您的网站 但是一旦您决定发送该推送消息 我可以在接下来发生的事情中 为您提供帮助 还记得推送请求 是如何安装到 Service Worker 的吗 一旦您的服务器发送了推送消息 Safari 浏览器便会接收到它 就会唤醒您的 Service Worker 并向其发送一个 JavaScript 推送事件 在通知中心 向用户显示通知 是处理推送事件时的要求 如果您的网站当时 在浏览器选项卡中处于打开状态 网站就会接收推送事件 并显示通知发生 如果您的网站当前未在浏览器 选项卡中打开 这种情况也会发生 对于 macOS Ventura 上的 Safari 浏览器 即使 Safari 浏览器当前未运行 也会发生这种情况 最后一步 如果您的用户点击了那个通知 一个通知点击事件就会被 发送到您的 Service Worker 这样它就会适时响应 例如 通过打开一个新窗口 让 URL 与该通知相关联 我们带您了解了网页推送流程 现在要通过 向现有的网络 App 实际添加网页推送支持 来了解更多细节 除了 webkit.org Browser Pet 对于 Safari 浏览器和 WebKit 团队来说 是最关键任务的内部工具 让部门每个人对他们最喜欢的 WebKitten 和 Pup 在 Safari 浏览器保持更新 一直是 Browser Pet 的使命 而网页推送让这比以往更加容易 我们内部的 BrowserPet 域 已经有一个 ServiceWorker 脚本被注册 以加快页面加载 并在多个选项卡之间同步 概括地说 ServiceWorker 脚本 和这有很大的相似之处 当工程师访问 选项卡中的 Browser Pet 页面时 这个 JavaScript 摘录将确定 Service Worker 脚本 是否已经注册 或在必要时注册 注意 前面提到 我们在这里练习的功能检测 是最佳实践 使用 Service Worker 先决条件已搞定 我们准备好订阅推送了 请记住 没有明确的用户手势 您不能要求推送订阅 运行此脚本作为 按钮的 onclick 处理程序的响应 是满足该要求的多种方式之一 用户点击该按钮之后 这里就有了推送订阅的请求代码 我将对这几点进行更深层次的探讨 首先 我们需要配置推送订阅请求 重要的一点是在我们的服务器上 使用公钥 到 Apple 推送服务器上识别自已 这里 我们使用的标准技术叫做 VAPID 和其他浏览器一样 有时候 我们不会再 在这里重复 VAPID 的细节 但是网上有资源来帮助您 在您的的服务器设置中 使用最好的解决方案 有了 VAPID 密钥集 我们就准备好配置订阅请求了 请注意 我们明确说明 我们承诺永远使推送用户可见 当 JavaScript Push API 标准 选择在 JavaScript 运行时 对推送不予回应 是大多数浏览器所不予支持的 Safari 浏览器不支持这种情况 和大多数网站一样 Browser Pet 不需要这种情况 然后我们请求推送权限 对于权限提示中的 这行 JavaScript 结果 用户可以选择批准或拒绝 假设用户授予权限 为了 Browser Pet 所有 Safari 浏览器团队成员都会这样做 这会给我们一个 PushSubscription 对象 它详细说明了如何在用户们的 浏览器中接触到他们 URL 端点以及密钥等 可用于把中转的推送消息加密 最后 我们需要把所有这些细节 发送到我们的服务器上 正如先前所说 基于您的具体应用 具体情况会有所不同 我们的 BrowserPet 服务器 使用 WordPress 已经有一些插件用于支持 标准网页推送 很可能您在后端会发现同样的情况 而且网上有资源 能帮助找到几乎任何设置的 正确解决方案 现在我们需要回到 我们的 Service Worker JavaScript 代码 它需要处理一些 从推送事件开始的新事件 当推送消息从 Browser Pet 服务器 换到这个浏览器时 这个 Service Worker 就会收到一个推送事件 这个引用名 包含 PushMessageData 对象 获取您的服务器发送的数据 有多种方式 我们在这里使用 JSON 访问器 记住 当我们订阅推送时 我们承诺的 JavaScript 始终是用户可见的吗 这意味着我们在响应每次推送时 必须始终显示为平台本机通知 最好在您的推送事件处理中 尽早执行此操作 我们正全力从那个 JSON blob 中 配置通知 包括使用 URL 设置操作 这很快就会派上用场 显示通知后 我们需要让用户点击它 我们的 Service Worker 脚本 还有一个事件要处理 在这个 notificationclick 处理程序中 BrowserPet 将从被点击的通知中 获取 URL 以打开一个新窗口 注意 这是一种非常常见的模式 这是所有我们需要写入的 JavaScript 我们需要用它来支持网页推送 当然 最好是在开发过程中 获得一些帮助 和往常一样 这是 Web Inspector 的用武之地 除了帮助 您的网站在浏览器选项卡中打开 Web Inspector 还可以检查 Service Worker 实例 并在事件处理程序上设置断点 这一切会让您检查和调试 订阅推送的 JavaScript 以及处理推送事件 和通知事件的服务人员代码 此外 Apple 推送通知服务器 在您试图发布推送消息的时候 如果出现了问题 那么就会出现一些人类可读性错误 查看与这次讲座相关的更多链接 以获取更多资料 在编写该代码时 我想就用户隐私 和电源使用提出的几点 进行更详细的讲解 重要的是 我不是第一次这么说了 订阅推送需要用户手势 与其他网络平台的特权功能一样 对于用户来说 在实际当中 要求用户在启用网页推送时 先回答问题是正确的选择 正如我向您展示代码时所提到的 关于如何请求推送订阅一样 您必须保证 推送的内容是用户可见的 处理推送事件 对您的 JavaScript 来说 并不是让您获得静默后台运行 这样做会破坏用户的信任 和用户的电池寿命 事实上 在处理推送事件时 您必须 向通知中心发送通知 其它浏览器都有 用以确保推送用户可见的 反对违反承诺对策 Safari 浏览器也是如此 在 macOS Ventura 的 Beta 版本中 在三个推送事件之后 您未能及时发布通知 您网站的推送订阅将被撤销 您将需要通过 再次访问权限的工作流程 就是这样 我们为支持网页推送感到由衷的自豪 并且很高兴任何网站都可以使用它 无需 Apple 开发者帐户 只要您按照标准编码并使用功能检测 您就不会在不知不觉中排除 Safari 浏览器 您的用户就会 在 macOS Ventura 上的 Safari 16 中 获得网页推送的好处 和往常一样 今年我们已经为 Safari 浏览器 和 WebKit 添加了很多其它的新功能 我希望您能看一看那个讲座 并了解更多 感谢收看 祝您余下的 WWDC 2022 之旅一切顺利
-
-
8:27 - BrowserPetsWorker.js
// BrowserPetsWorker.js function handleMessageEvent(event) { // ... }; self.addEventListener('message', (event) => { handleMessageEvent(event); }); function primeCaches() { // ... }; self.addEventListener('install', (event) => { primeCaches(); }); self.addEventListener('fetch', (event) => { event.respondWith(caches.match(event.request)); });
-
8:42 - BrowserPetsMain.js
// BrowserPetsMain.js var registration; if ('serviceWorker' in navigator) { let registration = await navigator.serviceWorker.getRegistration(); if (!registration) registration = await navigator.serviceWorker.register('BrowserPetsWorker.js'); }
-
9:00 - BrowserPetsMain.js subscribeToPush()
// BrowserPetsMain.js async function subscribeToPush() { // ... } // BrowserPetsMain.html <button onclick="subscribeToPush()">Register for Updates</button>
-
9:19 - BrowserPetsMain.js subscribe
// BrowserPetsMain.js async function subscribeToPush() { let serverPublicKey = VAPID_PUBLIC_KEY; let subscriptionOptions = { userVisibleOnly: true, applicationServerKey: serverPublicKey }; let subscription = await swRegistration.pushManager.subscribe(subscriptionOptions); sendSubcriptionToServer(subscription); }
-
9:36 - BrowserPetsMain.js subscriptionOptions
// BrowserPetsMain.js async function subscribeToPush() { let serverPublicKey = VAPID_PUBLIC_KEY; let subscriptionOptions = { userVisibleOnly: true, applicationServerKey: serverPublicKey }; let subscription = await swRegistration.pushManager.subscribe(subscriptionOptions); sendSubcriptionToServer(subscription); }
-
10:21 - BrowserPetsMain.js request permission to push
// BrowserPetsMain.js async function subscribeToPush() { let serverPublicKey = VAPID_PUBLIC_KEY; let subscriptionOptions = { userVisibleOnly: true, applicationServerKey: serverPublicKey }; let subscription = await swRegistration.pushManager.subscribe(subscriptionOptions); sendSubcriptionToServer(subscription); }
-
11:13 - BrowserPetsWorker.js push
// BrowserPetsWorker.js self.addEventListener('push', (event) => { let pushMessageJSON = event.data.json(); // Our server puts everything needed to show the notification // in our JSON data. event.waitUntil(self.registration.showNotification(pushMessageJSON.title, { body: pushMessageJSON.body, tag: pushMessageJSON.tag, actions: [{ action: pushMessageJSON.actionURL, title: pushMessageJSON.actionTitle, }] })); }
-
12:06 - BrowserPetsWorker.js notification click
// BrowserPetsWorker.js self.addEventListener('notificationclick', async function(event) { if (!event.action) return; // This always opens a new browser tab, // even if the URL happens to already be open in a tab. clients.openWindow(event.action); });
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。