百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

2024 年 PWA 无法与 Native 媲美的 7 个特性

zhezhongyun 2025-02-16 23:43 64 浏览

家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

最近读到一篇关于 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 API

Contacts 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)

NFC

Web 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 代码:


Based on the code snippets from specification draft.

Ambient Light

Ambient 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 API

Geofencing 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 Sensors

Proximity 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/

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...