现代 web 应用(如 vscode.dev)可通过 file system access api 直接读写用户本地文件与目录,无需后端代理或 `` 上传,但需 https 环境、用户显式授权及浏览器支持。
Web 应用传统上无法直接访问本地文件系统——这是浏览器沙箱安全模型的核心原则。然而,随着 File System Access API 的成熟(Chrome 86+、Edge 91+、Firefox 125+ 支持),前端 now 可以在用户明确授权的前提下,以安全、可控的方式操作本地文件和目录,真正实现“类桌面应用”的体验。
// 1. 请求打开单个文件(支持多选)
async function openAndEditFile() {
try {
const [fileHandle] = await window.showOpenFilePicker({
types: [{
description: 'Text files',
accept: { 'text/plain': ['.txt', '.md'] }
}]
});
// 2. 读取当前内容
const file = await fileHandle.getFile();
const content = await file.text();
console.log('Current content:', content);
// 3. 写入新内容(覆盖)
const writable
= await fileHandle.createWritable();
await writable.write('Hello from the web!\nUpdated at ' + new Date().toISOString());
await writable.close();
alert('File updated successfully!');
} catch (err) {
console.error('Operation failed:', err.name, err.message);
}
}async function manageDirectory() {
try {
const dirHandle = await window.showDirectoryPicker();
// 列出所有文件(不包含子目录)
for await (const entry of dirHandle.values()) {
if (entry.kind === 'file') {
console.log('Found file:', entry.name);
// 示例:将 .txt 文件重命名为 .bak(需先复制再删除)
if (entry.name.endsWith('.txt')) {
const newHandle = await dirHandle.getDirectoryHandle(
entry.name.replace(/\.txt$/, '.bak'),
{ create: true }
);
// ⚠️ 注意:API 不直接支持 rename;需 copy + delete
await entry.copyTo(dirHandle, entry.name.replace(/\.txt$/, '.bak'));
await entry.remove();
}
}
}
} catch (err) {
if (err.name === 'NotAllowedError') {
alert('User denied access — please try again and grant permission.');
} else {
console.error(err);
}
}
}File System Access API 并非替代后端文件服务,而是为离线优先、本地优先的 Web 应用(如代码编辑器、笔记工具、音视频处理应用)提供了关键能力。合理运用它,能让 Web 应用真正跨越“浏览器”与“操作系统”的边界,走向更强大的原生体验。