关于 "Project Fugu"
Project Fugu 致力于填补 Web 功能的空缺,从而使更多的应用能够在 web 端运行。
Project Fugu 大概在 2018 年就被提起,至于为什么现在又要重新提起它呢,因为围绕它的 API 发生了很重大的变化。
Project fugu 现在提供的新 API 能在保护网络安全的前提下,给应用带来全新的体验,例如本地文件系统的读写,已安装应用的获取,本地字体的获取等等。
关于 "Fugu"
源自于日语中的河豚(发音),寓意是处理好了就会很美味,处理不好就可能会很危险。
就比如在 Web 上直接访问文件系统,虽然在 Web 上便捷的删除文件看起来很酷,但如果你删除了对计算运行来说至关重要的文件,则可能带来严重的后果。因此 Project Fugu 给予了访问文件系统的能力的同时,限制了你访问系统文件的能力,这就类似对河豚的处理,确保处理是完好的。
Project fugu collaborators
Project fugu 是跨公司努力的结果,合作方主要是 Google、Intel 和 Microsoft 以及 Electron 等。(intel 参与进来是因为调研发现,人们在使用电脑时,会把 60% 的时间投入到 web 中)。
也意味着支持 Fugu 的浏览器包括 Microsoft 的 Edge,以及 chrome,因为 Electron 能直接使用 chromium 暴露的 API,可以减少对 NodeJS 库的依赖。
Fugu 月度同步:链接
Fugu showcase
developer.chrome.com/docs/capabi... 列出了相关应用,通过官方的图片大概能知道 Fugu 的应用范围:
拆分功能能够知道这些 API 的运用:蓝牙,游戏手柄,文件,徽标,通讯录等等。
How Fugu is my browser?
如果你系那个知道你的浏览器支持哪些 Fugu 的 API,可以通过 howfuguismybrowser.dev/ 看到各个 Fugu API 在你的浏览器上的支持情况:
Project fugu API 的应用
showDirectoryPicker
- vscode.dev
- photoshop online
- 腾讯文档
- ...
尝试用 vscode.dev 打开一个本地项目
如前面提到的,Firefox 不在 Fugu 合作者里面,所以对 Fugu 的 API 支持情况不太好,该 API 火狐就没有提供,我们尝试在 Firefox 中 打开一个本地项目:
只支持打开远端项目。
typescript
await showDirectoryPicker()
showDirectoryPicker
方法会返回一个 FileSystemDirectoryHandle
,不同于文件,文件是直接可以通过 FileReader 读/写的,文件夹涉及到安全因素等,调用的时候浏览器会向用户申请权限:
上图所示的是读权限,如果你想获取"写"权限:
ts
await showDirectoryPicker({ mode: 'readwrite' });
它就变成了请求写权限:
用户拒绝会返回一个取消请求的错误:
首次调用 showDirectoryPicker
方法,返回的是 FileSystemDirectoryHandle
,当然对应的肯定也是存在 FileSystemFileHandle
方法,二者可以通过返回的 kind
区分。
文件夹是可以包含文件夹和文件的,该对象可以获取子目录的文件夹和文件,如何获取文件夹的所有文件,需要用户递归去处理。
ts
const dirHandle = await window.showDirectoryPicker();
let result = [];
for await (const value of dirHandle.values()) {
result.push(value);
}
console.log(result);
PS: 后续会出一篇 "实现简易 vscode.dev" 的文章,就是基于该 API 实现的
EyeDropper API
3D模型编辑器 blockbench web 端能够在屏幕任何地方提取颜色。
类似的功能只能在 <input type="color" />
上看到,但没法单独使用,现在我们可以使用该 API 在屏幕的任何地方拾取颜色:
ts
const eyeDropper = new EyeDropper();
await eyeDropper.open();
showSaveFilePicker
常用到的绘图工具 excalidraw,当你在 Firefox 中保存时,执行的其实是下载操作,在 Chrome 中保存时才是文件的"保存"操作。
Firefox 中:
Chrome 中:
向文件 aba.txt
中写入 balabala
,
ts
const writable = await (
await showSaveFilePicker({
suggestedName: "aba.txt",
})
).createWritable();
await writable.write("balabala");
await writable.close();
PS: 文件的写操作出于安全设计等因素,过程是先建立一个临时文件,后续写的操作都是在临时文件上,执行的,在执行 close
方法以后会删掉临时文件,把临时文件的内容写到目标文件中,你可以试试。
该 API 另一个妙用是可以用在下载功能上,传统的实现,我们要在 Web 端实现下载,需要怎么做?创建一个虚空 a 标签,设置它的 download 属性,执行 click 方法。
现在,我们不需要这么做了,我们只需要(实际业务中已经这么做了,内部平台):
Shape Detection
- BarcodeDetector
- FaceDetector(feature)
- TextDetector(feature)
目前只有条形码的检测是正式发布了,人脸检测和文本检测因为检测质量不高,还未正式发布。使用条形码:
...
还有很多 API,更多的可以通过 howfuguismybrowser.dev/ 查询,一一去介绍这些 API 也是比较乏味的。
总结
Fugu 的 API 的引入使得开发人员能够构建更强大、更功能丰富的 Web 应用程序,提供更接近原生应用程序的体验。
而且,Project fugu 是一个持续进行的项目,谷歌团队正在不断添加新的API和功能,以进一步改进 Web 平台的能力。因此,以上列举的 API 只是其中的一部分,未来可能会有更多的功能被添加进来。
这些 API 也一定程度上增强了 PWA 应用的能力,excalidraw 团队就放弃了其 electron 版本,而去维护 PWA 应用,至于原因, blog 说明了为什么放弃,总结是因为 Fugu 带来的文件系统 + 粘贴板访问 + 声明链接捕获等等。