大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
最近读到一篇关于 PWA 的文章《 WHAT WEB CAN DO TODAY?》,加上本身自己对 PWA 这个专题也比较感兴趣,所以抽空梳理了 PWA 目前主流功能以及简单功能描述,文章已经发表在《2024 年 PWA 不温不火,40 + 逆天特性已出世!》。
本文重点列举 PWA 目前还没有实现的主流功能,包括:Contacts API、SMS/MMS、NFC、Ambient Light、Inter-App Sharing、Geofencing API、Proximity Sensors 等等。
Contacts APIContacts API 为特权 Web 应用程序提供了对系统中维护的用户地址簿的编程访问权限。截至 2020 年初,唯一的实现可在 Google Chrome 80+ 中使用。 Contacts API 专门针对选择仅在客户端应用程序中使用的联系人的只读场景,而且该 API 不支持任何修改。 Contacts API 调用平台级联系人选择器,并仅向查询应用程序公开用户选择的数据。仅适用于 Android
Contacts API 的初始版本是在 2013 年为 Firefox OS 创建的,并在 Firefox 中实现,其允许通过类似 vCard 的格式读取和修改联系人, 但由于实施缺陷很快就被禁用了。
无论是否以编程方式访问 Contacts API 的可用性,Web 应用程序都可能要求借助表单元素的 autocomplete 属性值从设备地址簿中预填充表单数据。
function readContacts() { var api = (navigator.contacts || navigator.mozContacts); if (api && !!api.select) { // 新的 Chrome API api.select(['name', 'email'], {multiple: true}) .then(function (contacts) { consoleLog('Found' + contacts.length + 'contacts.'); if (contacts.length) { consoleLog('First contact:' + contacts[0].name + '(' + contacts[0].email + ')'); } }) .catch(function (err) { consoleLog('Fetching contacts failed:' + err.name); }); } else if (api && !!api.find) { // 老的 Firefox OS API var criteria = { sortBy: 'familyName', sortOrder: 'ascending' }; api.find(criteria) .then(function (contacts) { consoleLog('Found' + contacts.length + 'contacts.'); if (contacts.length) { consoleLog('First contact:' + contacts[0].givenName[0] + ' ' + contacts[0].familyName[0]); } }) .catch(function (err) { consoleLog('Fetching contacts failed:' + err.name); }); } else { consoleLog('Contacts API not supported.'); }}function consoleLog(data) { var logElement = document.getElementById('log'); logElement.innerHTML += data + '\n';}SMS(Short Message Service)/MMS(Multimedia Messaging Service)Messaging API 的目标是允许 Web 应用程序完全访问设备上的 SMS 和 MMS 消息系统,旨在涵盖本机移动消息应用程序的功能,包括:浏览、创建和管理消息。 Messaging 的早期版本与后来的 Messaging API 提案不同,仅在现已不复存在的 Firefox OS 上实现,并且它是 Web 中 SMS 消息传递的唯一实际实现 。由于隐私和安全原因,没有浏览器供应商实现。
然而,存在一个 Web OTP API 提案,重点关注使用 SMS 作为传输方式传递一次性密码消息的更狭窄的任务。
navigator.messaging.sms.send(number, message, serviceId)navigator.messaging.mms.send(content)navigator.messaging.findMessages(filter, options)// 下面是火狐实现navigator.mozSms.send(number, message)navigator.mozSms.getMessages(filter)NFCWeb NFC API 是一种底层 API,使站点能够读取和写入附近的 NFC(近场通信)设备。其允许启动扫描,在 NFC 标签被点击时发出通知,其还提供了一种通过 NFC 写入消息的方法。
当前的支持仅限于 Chrome 中的实验性实现,可在 Android 上的 “experimental-web-platform-features” 标志后面使用。 还有 Firefox OS 实验性实现,但带有 moz 前缀,并且不遵循规范草案的当前状态。
async function readTag() { if ("NDEFReader" in window) { const ndef = new NDEFReader(); // NFC Reader try { await ndef.scan(); ndef.onreading = event => { const decoder = new TextDecoder(); for (const record of event.message.records) { consoleLog("Record type:" + record.recordType); consoleLog("MIME type:" + record.mediaType); consoleLog("=== data ===\n" + decoder.decode(record.data)); } } } catch(error) { consoleLog(error); } } else { consoleLog("Web NFC is not supported."); }}async function writeTag() { if ("NDEFReader" in window) { const ndef = new NDEFReader(); try { await ndef.write("What Web Can Do Today"); consoleLog("NDEF message written!"); } catch(error) { consoleLog(error); } } else { consoleLog("Web NFC is not supported."); }}function consoleLog(data) { var logElement = document.getElementById('log'); logElement.innerHTML += data + '\n';}下面是具体的 HTML 代码:
<p> <button onclick="readTag()">Test NFC Read</button> <button onclick="writeTag()">Test NFC Write</button></p><pre id="log"></pre><p><small>Based on the code snippets from <a href="https://w3c.github.io/web-nfc/#examples">specification draft</a>.</small></p>Ambient LightAmbient Light 允许 Web 应用程序访问设备光传感器(通常内置于设备摄像头中)测量的光强度级别。
第一种支持 Web 上光强度传感器的方法(作为独立的 API)早在 2013 年就在 Firefox 中实现了,从那时起,该规范被重写以利用新的通用传感器 API。 截至 2020 年初,这种风格仅在 Google Chrome 中实验性地实现,位于 “Generic Sensor Extra Classes” 标志后面。
function update(illuminance) { document.getElementById("value").innerHTML = illuminance + "lux"; var colorPart = Math.min(255, illuminance).toFixed(0); document.getElementById("box").style.backgroundColor = "rgb(" + colorPart + "," + colorPart + "," + colorPart + ")";}if ("AmbientLightSensor" in window) { // 访问光传感器 try { var sensor = new AmbientLightSensor(); sensor.addEventListener("reading", function (event) { update(sensor.illuminance); }); sensor.start(); } catch (e) { console.error(e); }}if ("ondevicelight" in window) { function onUpdateDeviceLight(event) { update(event.value); } window.addEventListener("devicelight", onUpdateDeviceLight);}Inter-App Sharing开发者曾多次尝试建立从 Web 应用程序到本机应用程序或其他 Web 应用程序的通用、多平台、异步数据交换方式。 自 2017 年以来推出的 Web Share API 实现可在 Android 和 iOS 上使用,它包含一个调用特定于平台的共享机制的方法,并向其传递命名 URL。 此外,Android 上的 Google Chrome 支持共享文件对象。
自 Chrome 71(2018 年底)以来,Android 中提供了一个补充性的 Web Share Target API,允许注册已安装的 Web 应用程序以在特定于平台的共享机制中可用,本质是基于应用程序清单文件中的 share_target 定义。 这样,用户就可以从系统中安装的任何其他应用程序(Web 或本机)将数据发送到应用程序中的指定端点。
从历史上看,几乎没有用于将数据发送到可能仍然相关的其他应用程序的基本解决方法。 本机应用程序可以注册处理程序以使用特殊的 URL 前缀从 Web 应用程序接收数据(尽管 iOS 和 Android 之间存在差异)。 还有第三方非标准服务来协调 Web 应用程序之间的数据共享。
解决 Web 数据共享问题的首次尝试,即 Web Intents 实验性 API 是在 Google Chrome 18(2012 年)中实现的,在概念上是基于 Android Intents 系统。 有兴趣接收数据的应用程序需要在 Chrome Web Store 中注册,并在清单文件中声明意图支持。 发送数据的应用程序能够调用特定类型的 Intent,并让系统处理目标应用程序的选择及其正确的调用。
由于各种互操作性和可用性问题,该 API 在 Chrome 24 中被删除,没有其他供应商实现 Web Intents。
function share() { if (!("share" in navigator)) { alert('Web Share API not supported.'); return; } // 分享 navigator.share({ title: 'What Web Can Do Today', text: 'Can I rely on the Web Platform features to build my app? An overview of the device integration HTML5 APIs', url: 'https://whatwebcando.today/' }) .then(() => console.log('Successful share')) .catch(error => console.log('Error sharing:', error));}function intent() { if (!("Intent" in window)) { alert('Web Intents API not supported.'); return; } var intent = new Intent('http://webintents.org/share', 'text/uri-list', 'https://whatwebcando.today'); navigator.startActivity(intent, function () { console.log('Successful share') }, function (error) { console.log('Error sharing:', error); });}Geofencing APIGeofencing API 允许授权的 Web 应用程序定义地理区域并在设备进入或离开这些区域时接收通知,而无需定期查询地理定位 API。 由于采用的 Service Worker 允许在所属 Web 应用程序的生命周期之外执行代码,因此当应用程序未在浏览器中打开时也可能会收到通知。
截至 2020 年初,没有供应商实现该 API,该提案似乎已被放弃。
region = new CircularGeofenceRegion({name, latitude, longitude, radius})serviceWorkerRegistration.geofencing.add(region, options)self.addEventListener('geofenceenter', listener)self.addEventListener('geofenceleave', listener)然而,Google Chrome 正在试验一个新概念,它可能会涵盖未来地理围栏的某些方面,即基于位置的通知触发器。
Proximity SensorsProximity Sensors API 允许 Web 应用程序访问来自设备接近传感器的数据,检测设备附近是否有物理对象。
第一种在 Web 上支持接近传感器的方法(作为独立的 API)是在 Firefox 中实现的。 从那时起,该规范被重写以利用新的通用传感器 API,但截至 2020 年初,没有供应商实现该规范。
var box = document.getElementById('box');function onDeviceProximityChanged(event) { document.getElementById('deviceValue').innerHTML = event.value + 'cm (' + event.min + '-' + event.max + 'cm range)'; var size = Math.min(200, Math.max(20, 500 / (event.value || 1))); box.style.width = size + 'px'; box.style.height = size + 'px';}function onUserProximityChanged(event) { document.getElementById('nearValue').innerHTML = event.near ? 'near' : 'rather far'; box.style.backgroundColor = event.near ? 'red' : 'green';}// deviceproximity 事件window.addEventListener('deviceproximity', onDeviceProximityChanged);window.addEventListener('userproximity', onUserProximityChanged);参考资料https://whatwebcando.today/
https://whatwebcando.today/proximity.html
https://whatpwacando.today/
https://www.allperfectstories.com/what-is-the-future-of-pwa-apps/
https://cedcommerce.com/blog/popular-pwa-queries-of-merchants-answered/
https://appicsoftwares.com/blog/is-pwa-the-right-choice/