File System Access API memungkinkan aplikasi web membaca atau menyimpan perubahan secara langsung ke file dan folder di perangkat pengguna.
Apa yang dimaksud dengan File System Access API?
File System Access API memungkinkan developer membuat aplikasi web canggih yang dapat berinteraksi dengan pada perangkat lokal pengguna, seperti IDE, editor foto dan video, editor teks, dan banyak lagi. Sesudah pengguna memberikan akses aplikasi web, API ini memungkinkan mereka untuk membaca atau menyimpan perubahan secara langsung ke file dan folder di perangkat pengguna. Selain membaca dan menulis file, File System Access API menyediakan kemampuan untuk membuka direktori dan menghitung isinya.
Jika Anda pernah bekerja membaca dan menulis {i>file<i} sebelumnya, sebagian besar hal yang akan saya bagikan tidak asing bagi Anda. Saya mendorong Anda untuk tetap membacanya, karena tidak semua sistem itu sama.
File System Access API didukung di sebagian besar browser Chromium di Windows, macOS, ChromeOS, dan Linux. Satu pengecualiannya adalah Brave, saat ini hanya tersedia di balik flag. Dukungan untuk Android sedang dikerjakan dalam konteks crbug.com/1011535.
Menggunakan File System Access API
Untuk menunjukkan kemampuan dan kegunaan File System Access API, saya menulis satu teks file editor video. {i>File<i} teks memungkinkan Anda membuka file teks, mengeditnya, menyimpan perubahan kembali ke {i>disk<i}, atau memulai file baru dan menyimpan perubahan ke {i>disk<i}. Tidak ada yang mewah, tetapi sudah cukup untuk membantu Anda memahami konsep.
Dukungan browser
Deteksi fitur
Untuk mengetahui apakah File System Access API didukung, periksa apakah metode pemilih yang Anda minati.
if ('showOpenFilePicker' in self) {
// The `showOpenFilePicker()` method of the File System Access API is supported.
}
Coba
Lihat cara kerja File System Access API di demo editor teks.
Membaca file dari sistem file lokal
Kasus penggunaan pertama yang ingin saya tangani adalah meminta pengguna untuk memilih file, lalu membuka dan membacanya file dari disk.
Minta pengguna memilih file untuk dibaca
Titik entri ke File System Access API adalah
window.showOpenFilePicker()
Saat dipanggil, dialog pemilih file akan muncul,
dan meminta pengguna
untuk memilih file. Setelah mereka memilih file, API akan menampilkan array file
nama sebutan channel. Parameter options
opsional memungkinkan Anda memengaruhi perilaku pemilih file, untuk
contohnya, dengan mengizinkan pengguna memilih
beberapa file, direktori, atau jenis file yang berbeda.
Tanpa opsi yang ditentukan, pemilih file memungkinkan pengguna memilih satu file. Ini adalah
sangat cocok untuk editor teks.
Seperti banyak API canggih lainnya, memanggil showOpenFilePicker()
harus dilakukan dengan cara aman
konteks, dan harus dipanggil dari dalam gestur pengguna.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
// Destructure the one-element array.
[fileHandle] = await window.showOpenFilePicker();
// Do something with the file handle.
});
Setelah pengguna memilih file, showOpenFilePicker()
akan menampilkan array tuas, dalam hal ini
array satu elemen dengan satu FileSystemFileHandle
yang berisi properti dan
metode yang diperlukan
untuk berinteraksi dengan file tersebut.
Sebaiknya Anda menyimpan referensi ke handle file agar dapat digunakan nanti. Ini akan menjadi yang diperlukan untuk menyimpan perubahan pada file, atau melakukan operasi file lainnya.
Membaca file dari sistem file
Setelah memiliki handle untuk file, Anda bisa mendapatkan properti file, atau mengakses file itu sendiri.
Untuk saat ini, saya akan
membaca isinya. Memanggil handle.getFile()
akan menampilkan File
, yang berisi blob. Untuk mendapatkan data dari blob, panggil salah satu
metode, (slice()
,
stream()
,
text()
, atau
arrayBuffer()
).
const file = await fileHandle.getFile();
const contents = await file.text();
Objek File
yang ditampilkan oleh FileSystemFileHandle.getFile()
hanya dapat dibaca selama
file sumber pada {i>disk<i} tidak berubah. Jika file pada disk diubah, objek File
menjadi
tidak dapat dibaca dan Anda harus memanggil getFile()
lagi untuk mendapatkan objek File
baru agar dapat membaca perubahan
layanan otomatis dan data skalabel.
Menggabungkan semuanya
Saat pengguna mengklik tombol Open, browser akan menampilkan pemilih file. Setelah mereka memilih file,
aplikasi membaca konten dan menempatkannya ke dalam <textarea>
.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
textArea.value = contents;
});
Menulis file ke sistem file lokal
Di editor teks, ada dua cara untuk menyimpan file: Save dan Save As. Simpan menulis perubahan kembali ke file asli menggunakan {i>handle file<i} yang diambil sebelumnya. Tapi Simpan Sebagai akan membuat file baru, sehingga memerlukan handle file baru.
Membuat file baru
Untuk menyimpan file, panggil showSaveFilePicker()
yang menampilkan alat pilih file
di "simpan" mode, yang memungkinkan pengguna untuk memilih file
baru yang ingin mereka gunakan untuk menyimpan. Untuk teks
editor saya juga ingin otomatis menambahkan ekstensi .txt
, jadi saya memberikan beberapa
parameter.
async function getNewFileHandle() {
const options = {
types: [
{
description: 'Text Files',
accept: {
'text/plain': ['.txt'],
},
},
],
};
const handle = await window.showSaveFilePicker(options);
return handle;
}
Simpan perubahan ke disk
Anda bisa menemukan semua kode untuk menyimpan perubahan ke file dalam demo editor teks saya di
di GitHub. Interaksi sistem file inti berada di
fs-helpers.js
Sederhananya, prosesnya terlihat seperti kode berikut.
Saya akan menjelaskan
setiap langkahnya.
// fileHandle is an instance of FileSystemFileHandle..
async function writeFile(fileHandle, contents) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
}
Menulis data ke disk menggunakan objek FileSystemWritableFileStream
, yang merupakan subclass
dari WritableStream
. Buat aliran data dengan memanggil createWritable()
pada file
menangani objek tersebut. Saat createWritable()
dipanggil, browser akan memeriksa terlebih dahulu apakah pengguna telah memberikan izin
izin akses tulis ke file. Jika izin untuk menulis belum diberikan, browser akan meminta
pengguna untuk meminta izin. Jika izin tidak diberikan, createWritable()
akan menampilkan
DOMException
, dan aplikasi tidak akan dapat menulis ke file. Di editor teks,
Objek DOMException
ditangani dalam metode saveFile()
.
Metode write()
mengambil string, yang diperlukan oleh editor teks. Tapi itu juga bisa memakan
BufferSource, atau Blob. Misalnya, Anda dapat menyalurkan streaming langsung ke
hal tersebut:
async function writeURLToFile(fileHandle, url) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Make an HTTP request for the contents.
const response = await fetch(url);
// Stream the response into the file.
await response.body.pipeTo(writable);
// pipeTo() closes the destination pipe by default, no need to close it.
}
Anda juga dapat seek()
, atau truncate()
dalam aliran data untuk memperbarui
di posisi tertentu, atau
mengubah ukuran file.
Menentukan nama file yang disarankan dan direktori awal
Dalam banyak kasus, Anda mungkin ingin aplikasi menyarankan nama file atau lokasi default. Misalnya, teks
mungkin ingin menyarankan nama file default Untitled Text.txt
, bukan Untitled
. Anda
dapat melakukannya dengan meneruskan properti suggestedName
sebagai bagian dari opsi showSaveFilePicker
.
const fileHandle = await self.showSaveFilePicker({
suggestedName: 'Untitled Text.txt',
types: [{
description: 'Text documents',
accept: {
'text/plain': ['.txt'],
},
}],
});
Hal yang sama berlaku untuk direktori awal {i>default<i}. Jika Anda membuat editor teks, Anda mungkin ingin
memulai dialog penyimpanan file atau pembukaan file di folder documents
default, sedangkan untuk gambar
Anda, sebaiknya mulai di folder default pictures
. Anda dapat menyarankan
memulai default
direktori dengan meneruskan properti startIn
ke showSaveFilePicker
, showDirectoryPicker()
, atau
Metode showOpenFilePicker
seperti itu.
const fileHandle = await self.showOpenFilePicker({
startIn: 'pictures'
});
Daftar direktori sistem yang dikenal adalah:
desktop
: Direktori desktop pengguna, jika ada.documents
: Direktori tempat dokumen yang dibuat oleh pengguna biasanya akan disimpan.downloads
: Direktori tempat file yang didownload biasanya disimpan.music
: Direktori tempat file audio biasanya disimpan.pictures
: Direktori tempat biasanya menyimpan foto dan gambar diam lainnya.videos
: Direktori tempat video atau film biasanya disimpan.
Terlepas dari direktori sistem yang dikenal, Anda juga dapat meneruskan file atau {i>handle<i} direktori yang ada sebagai
nilai untuk startIn
. Dialog kemudian akan terbuka di direktori yang sama.
// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
startIn: directoryHandle
});
Menentukan tujuan berbagai pemilih file
Terkadang aplikasi memiliki pemilih yang berbeda untuk tujuan yang berbeda. Misalnya, teks kaya
memungkinkan pengguna membuka file teks, tetapi juga mengimpor gambar. Secara default, setiap file
akan terbuka di lokasi yang terakhir diingat. Anda dapat mengakalinya dengan menyimpan nilai id
untuk setiap jenis pemilih. Jika id
ditentukan, implementasi pemilih file akan mengingat
direktori yang terakhir digunakan secara terpisah untuk id
tersebut.
const fileHandle1 = await self.showSaveFilePicker({
id: 'openText',
});
const fileHandle2 = await self.showSaveFilePicker({
id: 'importImage',
});
Menyimpan tuas file atau tuas direktori di IndexedDB
{i>File handle<i} dan {i>handle<i} direktori dapat diserialisasi, artinya Anda bisa menyimpan file atau
nama pengguna direktori ke IndexedDB, atau panggil postMessage()
untuk mengirimnya antara server induk
tempat asal.
Menyimpan handle direktori atau file ke IndexedDB berarti Anda dapat menyimpan status, atau mengingat status file atau direktori yang sedang dikerjakan oleh pengguna. Hal ini memungkinkan Anda menyimpan daftar yang baru saja dibuka atau file yang diedit, tawarkan untuk membuka kembali file terakhir saat aplikasi dibuka, pulihkan file sebelumnya direktori, dan banyak lagi. Di editor teks, saya menyimpan daftar lima file terbaru yang dimiliki pengguna terbuka, sehingga file-file tersebut dapat diakses kembali.
Contoh kode berikut menunjukkan penyimpanan dan pengambilan handle file dan handle direktori. Anda dapat lihat cara kerjanya di Glitch. (Saya menggunakan library idb-keyval agar lebih singkat.)
import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';
const pre1 = document.querySelector('pre.file');
const pre2 = document.querySelector('pre.directory');
const button1 = document.querySelector('button.file');
const button2 = document.querySelector('button.directory');
// File handle
button1.addEventListener('click', async () => {
try {
const fileHandleOrUndefined = await get('file');
if (fileHandleOrUndefined) {
pre1.textContent = `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const [fileHandle] = await window.showOpenFilePicker();
await set('file', fileHandle);
pre1.textContent = `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
// Directory handle
button2.addEventListener('click', async () => {
try {
const directoryHandleOrUndefined = await get('directory');
if (directoryHandleOrUndefined) {
pre2.textContent = `Retrieved directroy handle "${directoryHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const directoryHandle = await window.showDirectoryPicker();
await set('directory', directoryHandle);
pre2.textContent = `Stored directory handle for "${directoryHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
Handle dan izin file atau direktori yang disimpan
Karena izin tidak selalu dipertahankan di antara sesi, Anda harus memverifikasi apakah pengguna
telah memberikan izin ke file atau direktori menggunakan queryPermission()
. Jika belum, panggil
requestPermission()
untuk memintanya (ulang). Ini berfungsi sama untuk nama sebutan file dan direktori. Anda
perlu menjalankan fileOrDirectoryHandle.requestPermission(descriptor)
atau
fileOrDirectoryHandle.queryPermission(descriptor)
masing-masing.
Di editor teks, saya membuat metode verifyPermission()
yang memeriksa apakah pengguna sudah
diberi izin, dan jika diperlukan, membuat permintaan.
async function verifyPermission(fileHandle, readWrite) {
const options = {};
if (readWrite) {
options.mode = 'readwrite';
}
// Check if permission was already granted. If so, return true.
if ((await fileHandle.queryPermission(options)) === 'granted') {
return true;
}
// Request permission. If the user grants permission, return true.
if ((await fileHandle.requestPermission(options)) === 'granted') {
return true;
}
// The user didn't grant permission, so return false.
return false;
}
Dengan meminta izin tulis dengan permintaan baca, saya mengurangi jumlah dialog izin; pengguna melihat satu prompt saat membuka file, dan memberikan izin untuk membaca dan menulis file.
Membuka direktori dan menghitung isinya
Untuk menghitung semua file dalam direktori, panggil showDirectoryPicker()
. Pengguna
memilih direktori di pemilih, setelah itu FileSystemDirectoryHandle
akan
ditampilkan, yang memungkinkan Anda
menghitung dan mengakses file direktori. Secara {i>default<i}, Anda telah membaca
akses ke file dalam direktori, tetapi jika
Anda membutuhkan akses tulis, Anda dapat meneruskan
{ mode: 'readwrite' }
ke metode.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
});
Jika Anda juga perlu mengakses setiap file menggunakan getFile()
, misalnya, untuk mendapatkan
ukuran file, jangan gunakan await
pada setiap hasil secara berurutan, melainkan proses semua file dalam
paralel, misalnya, menggunakan Promise.all()
.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
const promises = [];
for await (const entry of dirHandle.values()) {
if (entry.kind !== 'file') {
continue;
}
promises.push(entry.getFile().then((file) => `${file.name} (${file.size})`));
}
console.log(await Promise.all(promises));
});
Membuat atau mengakses file dan folder dalam direktori
Dari direktori, Anda dapat membuat atau mengakses
file dan folder menggunakan
getFileHandle()
atau masing-masing getDirectoryHandle()
. Dengan meneruskan objek options
opsional dengan kunci create
dan nilai boolean
true
atau false
, Anda dapat menentukan apakah file atau folder baru harus dibuat jika tidak ada.
// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });
Menyelesaikan jalur item dalam direktori
Saat bekerja dengan file atau folder dalam direktori, sebaiknya tentukan jalur item
yang dimaksud. Hal ini dapat dilakukan dengan metode resolve()
yang diberi nama dengan tepat. Untuk menyelesaikan,
item dapat berupa turunan langsung
atau tidak langsung dari direktori.
// Resolve the path of the previously created file called "My Notes.txt".
const path = await newDirectoryHandle.resolve(newFileHandle);
// `path` is now ["My Documents", "My Notes.txt"]
Menghapus file dan folder di direktori
Jika Anda telah memperoleh akses ke direktori, Anda dapat menghapus file dan folder yang ada di dalamnya dengan
Metode removeEntry()
. Untuk folder, penghapusan dapat bersifat rekursif secara opsional dan termasuk
semua {i>subfolder<i} dan file
yang ada di dalamnya.
// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });
Menghapus file atau folder secara langsung
Jika Anda memiliki akses ke nama sebutan file atau direktori, panggil remove()
di FileSystemFileHandle
atau
FileSystemDirectoryHandle
untuk menghapusnya.
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
Mengganti nama serta memindahkan file dan folder
File dan folder dapat diganti namanya atau dipindahkan ke lokasi baru dengan memanggil move()
di
Antarmuka FileSystemHandle
. FileSystemHandle
memiliki antarmuka turunan FileSystemFileHandle
dan
FileSystemDirectoryHandle
. Metode move()
menggunakan satu atau dua parameter. Yang pertama bisa
berupa string dengan nama baru atau FileSystemDirectoryHandle
untuk folder tujuan. Di kolom
parameter kedua opsional adalah string dengan nama baru, sehingga memindahkan dan mengganti nama
terjadi dalam satu langkah.
// Rename the file.
await file.move('new_name');
// Move the file to a new directory.
await file.move(directory);
// Move the file to a new directory and rename it.
await file.move(directory, 'newer_name');
Integrasi tarik lalu lepas
Tujuan
Antarmuka Tarik lalu Lepas HTML
mengaktifkan aplikasi web untuk menerima
file yang ditarik lalu dilepas
pada sebuah laman web. Selama operasi tarik lalu lepas, file yang ditarik dan item direktori akan dikaitkan
masing-masing dengan entri file
dan entri direktori. DataTransferItem.getAsFileSystemHandle()
menampilkan promise dengan objek FileSystemFileHandle
jika item yang ditarik adalah file, dan
promise dengan objek FileSystemDirectoryHandle
jika item yang ditarik adalah direktori. Listingan berikut
menunjukkan cara kerjanya. Perhatikan, antarmuka Seret dan Lepas
DataTransferItem.kind
sama dengan
"file"
untuk file dan direktori, sedangkan FileSystemHandle.kind
File System Access API
"file"
untuk file dan "directory"
untuk direktori.
elem.addEventListener('dragover', (e) => {
// Prevent navigation.
e.preventDefault();
});
elem.addEventListener('drop', async (e) => {
e.preventDefault();
const fileHandlesPromises = [...e.dataTransfer.items]
.filter((item) => item.kind === 'file')
.map((item) => item.getAsFileSystemHandle());
for await (const handle of fileHandlesPromises) {
if (handle.kind === 'directory') {
console.log(`Directory: ${handle.name}`);
} else {
console.log(`File: ${handle.name}`);
}
}
});
Mengakses sistem file pribadi origin
Sistem file pribadi asal adalah endpoint penyimpanan yang, seperti namanya, bersifat pribadi
asal halaman. Sementara browser biasanya menerapkannya
dengan mempertahankan konten
sistem file pribadi asal ke disk di suatu tempat, konten tersebut tidak dimaksudkan untuk dijadikan
dapat diakses. Demikian pula, tidak diharapkan bahwa file atau direktori dengan nama yang cocok
nama turunan dari sistem file
pribadi asal yang ada. Meskipun {i>browser<i}
membuat tampak
ada file, secara internal—karena ini adalah sistem file privat asal—browser dapat menyimpan
“{i>file<i}” ini dalam {i>database<i} atau struktur data lainnya. Pada dasarnya, jika Anda menggunakan API ini,
tidak berharap menemukan file yang dibuat cocok satu-satu di suatu tempat pada hard disk. Anda dapat beroperasi seperti biasa di
sistem file pribadi origin setelah Anda memiliki akses ke root FileSystemDirectoryHandle
.
const root = await navigator.storage.getDirectory();
// Create a new file handle.
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
// Create a new directory handle.
const dirHandle = await root.getDirectoryHandle('New Folder', { create: true });
// Recursively remove a directory.
await root.removeEntry('Old Stuff', { recursive: true });
Mengakses file yang dioptimalkan untuk performa dari sistem file pribadi asal
Sistem file pribadi asal menyediakan akses
opsional ke jenis file khusus yang
dioptimalkan untuk kinerja, misalnya, dengan menawarkan akses tulis di tempat dan eksklusif ke
saat ini. Di Chromium 102 dan yang lebih baru, ada metode tambahan di sistem file pribadi origin untuk
menyederhanakan akses file: createSyncAccessHandle()
(untuk operasi baca dan tulis sinkron).
Halaman ini diekspos di FileSystemFileHandle
, tetapi secara eksklusif di
Pekerja Web.
// (Read and write operations are synchronous,
// but obtaining the handle is asynchronous.)
// Synchronous access exclusively in Worker contexts.
const accessHandle = await fileHandle.createSyncAccessHandle();
const writtenBytes = accessHandle.write(buffer);
const readBytes = accessHandle.read(buffer, { at: 1 });
Polyfill
Tidak mungkin mem-polyfill metode File System Access API sepenuhnya.
- Metode
showOpenFilePicker()
dapat diperkirakan dengan elemen<input type="file">
. - Metode
showSaveFilePicker()
dapat disimulasikan dengan elemen<a download="file_name">
, meskipun hal ini memicu download terprogram dan tidak memungkinkan untuk menimpa file yang ada. - Metode
showDirectoryPicker()
dapat diemulasikan dengan metode elemen<input type="file" webkitdirectory>
.
Kami telah mengembangkan library bernama browser-fs-access yang menggunakan File System Access API jika memungkinkan dan kembali ke opsi terbaik berikutnya di semua penggunaan.
Keamanan dan izin
Tim Chrome telah merancang dan menerapkan File System Access API menggunakan prinsip inti didefinisikan dalam Mengontrol Akses ke Fitur Platform Web yang Canggih, termasuk informasi kontrol dan transparansi, dan ergonomi pengguna.
Membuka file atau menyimpan file baru
![Pemilih file untuk membuka file yang akan dibaca](https://developer.chrome.google.cn/static/docs/capabilities/web-apis/file-system-access/image/file-picker-open-file-8cb5f6783ee89.jpg?authuser=1&hl=id)
Saat membuka file, pengguna memberikan izin untuk membaca file atau direktori menggunakan pemilih file.
Pemilih file yang terbuka hanya dapat ditampilkan menggunakan gestur pengguna saat disajikan dari server yang aman
konteks tambahan. Jika pengguna berubah pikiran, mereka dapat membatalkan pilihan dalam file
dan situs itu tidak
mendapatkan akses ke apa pun. Ini adalah perilaku yang
sama dengan yang
Elemen <input type="file">
.
![Pemilih file untuk menyimpan file ke disk.](https://developer.chrome.google.cn/static/docs/capabilities/web-apis/file-system-access/image/file-picker-save-file-bd54ae001799a.jpg?authuser=1&hl=id)
Demikian pula, saat aplikasi web ingin menyimpan file baru, browser menampilkan alat pilih simpan file, memungkinkan pengguna untuk menentukan nama dan lokasi file baru. Karena mereka menyimpan file baru ke perangkat (dibandingkan menimpa file yang sudah ada), pemilih file memberikan izin kepada aplikasi untuk menulis ke file.
Folder yang dibatasi
Untuk membantu melindungi pengguna dan data mereka, browser dapat membatasi kemampuan pengguna untuk menyimpan ke folder sistem operasi inti seperti Windows, folder Library macOS. Jika hal ini terjadi, browser akan menampilkan perintah dan meminta pengguna memilih folder tersebut.
Mengubah file atau direktori yang ada
Aplikasi web tidak dapat mengubah file pada disk tanpa mendapatkan izin eksplisit dari pengguna.
Dialog izin
Jika seseorang ingin menyimpan perubahan ke file yang sebelumnya mereka berikan akses baca, browser menampilkan prompt izin, yang meminta izin bagi situs untuk menulis perubahan ke disk. Permintaan izin hanya bisa dipicu oleh {i>gesture <i}pengguna, misalnya, dengan mengeklik tombol {i>Save<i} tombol.
![Permintaan izin yang ditampilkan sebelum menyimpan file.](https://developer.chrome.google.cn/static/docs/capabilities/web-apis/file-system-access/image/permission-prompt-shown-p-823d180f97ad5.png?authuser=1&hl=id)
Atau, aplikasi web yang mengedit beberapa file, seperti IDE, juga dapat meminta izin untuk menyimpan perubahan pada saat pembukaan.
Jika pengguna memilih Batal, dan tidak memberikan akses tulis, aplikasi web tidak dapat menyimpan perubahan pada file lokal. Harus menyediakan metode alternatif bagi pengguna untuk menyimpan data mereka, sebagai misalnya dengan menyediakan cara "mengunduh" file atau menyimpan data ke cloud.
Transparansi
![Ikon Omnibox](https://developer.chrome.google.cn/static/docs/capabilities/web-apis/file-system-access/image/omnibox-icon-5797e9a831603.jpg?authuser=1&hl=id)
Setelah pengguna memberikan izin kepada aplikasi web untuk menyimpan file lokal, browser akan menampilkan ikon di kolom URL. Mengklik ikon akan membuka pop-over yang menampilkan daftar file yang telah diberikan pengguna akses. Pengguna selalu dapat mencabut akses tersebut jika mau.
Persistensi izin
Aplikasi web dapat terus menyimpan perubahan ke file tanpa meminta izin hingga semua tab untuk origin ditutup. Setelah tab ditutup, situs tersebut akan kehilangan semua akses. Saat berikutnya pengguna menggunakan aplikasi web, mereka akan diminta kembali untuk mengakses file.
Masukan
Kami ingin mengetahui pengalaman Anda menggunakan File System Access API.
Beri tahu kami tentang desain API
Apakah ada sesuatu tentang API yang tidak berfungsi seperti yang Anda harapkan? Atau apakah ada metode yang hilang yang dibutuhkan untuk menerapkan ide Anda? Memiliki pertanyaan atau komentar tentang keamanan model?
- Laporkan masalah spesifikasi di repo GitHub Akses Sistem File WICG, atau tambahkan pendapat Anda terhadap masalah yang sudah ada.
Ada masalah dengan implementasinya?
Apakah Anda menemukan bug pada implementasi Chrome? Atau apakah implementasinya berbeda dengan spesifikasi?
- Laporkan bug di https://new.crbug.com. Pastikan untuk menyertakan detail sebanyak mungkin,
petunjuk untuk reproduksi, dan setel Komponen ke
Blink>Storage>FileSystem
. Glitch sangat cocok untuk berbagi repro cepat.
Anda berencana menggunakan API?
Berencana menggunakan File System Access API di situs Anda? Dukungan publik Anda membantu kami menentukan prioritas baru, dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung mereka.
- Bagikan rencana Anda untuk menggunakannya di thread Discourse WICG.
- Kirim tweet ke @ChromiumDev menggunakan hashtag
#FileSystemAccess
dan beri tahu kami tempat dan cara Anda menggunakannya.
Link bermanfaat
- Penjelasan untuk publik
- Spesifikasi Akses Sistem File & Spesifikasi file
- Bug pelacakan
- Entri ChromeStatus.com
- Definisi TypeScript
- File System Access API - Model Keamanan Chromium
- Komponen Kedipan:
Blink>Storage>FileSystem
Ucapan terima kasih
Spesifikasi File System Access API ditulis oleh Marijn Kruisselbrink.