Update 2024:
While it is still not possible to serialize the actual File
Object, a way more efficient solution to store the content for later upload (compared to serializing to base64) is possible thanks to the widely avaible origin private file system* (OPFS).
Below is a minimal Typescript example to store an array of File
objects with cacheFiles
and retrieving them with retrieveFiles
:
public async cacheFiles(files: File[]) Promise<void> {
const opfs = await navigator.storage.getDirectory();
for (let file of files) {
const handle = await opfs.getFileHandle(file.name, {create: true});
const stream = await handle.createWritable();
await stream.write(file);
await stream.close();
}
}
private async retrieveFiles(): Promise<File[]> {
const opfs = await navigator.storage.getDirectory();
const files: File[] = [];
for await (const fileEntry of opfs.values()) {
const fileHandle = await opfs.getFileHandle(fileEntry.name);
files.push(await fileHandle.getFile());
}
return files;
}
The retrieved array of File
s can then be used just like the FileList
returned by the files
attribute of HTMLInputElement with type=file
. Since 2023 the methods used in above example are available in all major browsers (MDN Baseline 2023).
An extensive guide with examples can be found at https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system .
Working with a File reference without copying the content, as described at https://developer.chrome.com/docs/capabilities/web-apis/file-system-access , should become possible once the File System Access API (https://wicg.github.io/file-system-access/#api-showopenfilepicker) is widely supported, namely the methods
window.showOpenFilePicker()
https://developer.mozilla.org/en-US/docs/Web/API/Window/showOpenFilePickerFileSystemHandle.requestPermission()
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/requestPermissionFileSystemHandle.queryPermission()
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/queryPermissionAs of December 2024, this is not the case!