To read a file, we needed to create an input tag of type=”file” for the user to select a file, and to save some content to the local disk, we needed to use the DOWNLOAD attribute of the A tag to trigger file saving.
Continuous file saving is not possible because writing files to the local disk must trigger the “save” box. It is also impossible to traverse a local directory.
In the latest release of Chrome 78, Google has enabled an experimental feature called Native File System, a new API for reading and writing Native files that is currently under development, so it is not enabled by default.
To check out the API, you can enable it by searching for the Native File System API in Chrome ://flags.
A brief introduction to the API can be found at github.com/WICG/native…
This is a new file read/write API that makes it easier to read/write files locally, but also introduces a significant security risk. Therefore, this API can only be invoked on secure pages (such as pages with valid HTTPS deployed). And it must be done by user choice (that is, not fully automated in the background).
Open and read the contents of the file
To read a local file, we need to call the window. The chooseFileSystemEntries (option) interface, it accepts a option as a parameter.
Option is an object containing four configuration items that can be configured:
Configuration items | The values | explain |
---|---|---|
type | 'openFile' /'saveFile' /'openDirectory' |
Operation type, open file, save file or open folder, default is'open-file' |
multiple | boolean |
Allows the user to select a single file or multiple files. The default isfalse , that is, only a single file can be selected |
accepts | object[] |
Specifies the file types that are allowed to be selected in the file selection box that is displayed |
accepts.description | string |
describe |
accepts.mimeTypes | string[] |
The MIME type of the file that is allowed to be selected |
accepts.extensions | string[] |
Extension of the file that is allowed to be selected |
excludeAcceptAllOption | boolean |
Whether to allow the option is not aboveaccepts File types allowed in the list. The default isfalse , which allows you to select any file (*. * ) |
Window. ChooseFileSystemEntries (option) returns a FileSystemHandle object (if multiple is specified in the option to true, Returns an array of FileSystemHandle.
FileSystemHandle is a base class, and actually chooseFileSystemEntries are based on the type specified in option, Return is it a subclass FileSystemFileHandle or FileSystemDirectoryHandle.
If the specified option is to open a folder, it returns FileSystemDirectoryHandle, can undertake directory traversal, can also open a specified file, open the file will return a FileSystemFileHandle. If the specified option is to open/save a file, FileSystemFileHandle is returned.
The getFile() function on FileSystemFileHandle provides a File object.
You can get the File object by calling the File object API. For text files, for example, you can call.text() to get a string. For binary files, You can call.arrayBuffer() to get an arrayBuffer object, or you can call.stream() to get a ReadableStream.
const handler = await window.chooseFileSystemEntries({
type: 'openFile'.accepts: [{description: 'Text file'.extensions: ['txt']},]});const file = await handler.getFile();
const text = await file.text();
console.log(text);
Copy the code
Save the file to the local hard disk
To save the file to hard disk, call createWriter() on the FileSystemFileHandle object.
There are usually two modes for saving files, one is “save”, which means overwriting the original file, and the other is “save as”, which means creating a new file.
The form of “save as”, we only need to call the window. The chooseFileSystemEntries () provides the option to save the file. To save the file, use the FileSystemFileHandle object of the previously opened file.
CreateWriter () returns a FileSystemWriter object containing three functions: write(position, data), truncate(size), and close().
The first argument to the write function, position, is a number indicating where to start writing, and the second argument is the data to write, This can be an ArrayBuffer object, an ArrayBufferView object (Uint8Array, DataView, etc.), a Blob object, or simply providing a string to write.
The truncate function truncates the file to a specified length. This usually occurs when the file to be saved is smaller than the original file. If you call write directly, only the first part of the file will be overwritten, but the contents of the original file will remain.
When createWriter() is invoked, the browser checks whether the user has permission to write files. If a file is opened in the Open file or open folder format, the user does not have permission to write files by default. If the user rejects the requested permission, an exception will be thrown.
const handler = await window.chooseFileSystemEntries({
type: 'saveFile'.accepts: [{description: 'Text file'.extensions: ['txt']},]});const writer = await handler.createWriter();
await writer.truncate(0); // Clear the file
await writer.write(0.'Hello World! '); // Write a string to the file header
await writer.close();
const file = await handler.getFile();
const text = await file.text();
console.log(text);
Copy the code
Go through the local directory
In the aforementioned window. ChooseFileSystemEntries () function, the option can be specified to open a folder, the browser will apply to the user directory traversal permissions, user permission, You can get a FileSystemDirectoryHandle object.
FileSystemDirectoryHandle object has a however () function, it returns an asynchronous iterator that can pass for await… of … Loop through the directory. Each iteration yields a FileSystemHandle object, According to. IsFile attributes and. IsDirectory property judgment is specific FileSystemFileHandle object or FileSystemDirectoryHandle object.
In addition to using however, traverse (), can also through getDirectory FileSystemDirectoryHandle object function opens a specified directory, Directories are also a FileSystemDirectoryHandle object; You can also use getFile to open a specified file and get FileSystemFileHandle.
const handler = await window.chooseFileSystemEntries({
type: 'openDirectory'});const ls = async (path, handler) => {
const result = [];
for await (const h of await handler.getEntries()) {
if (h.isFile) {
result.push(`${path}/${h.name}`);
} else if (h.isDirectory) {
const subDirectory = await ls(`${path}/${h.name}`, h);
result.push(...subDirectory);
}
}
return result;
};
const files = await ls(handler.name, handler);
console.log(files);
Copy the code
Security and Permissions
All apis of this new Native File System API are returned in the form of promises, which allow the browser to request and check all permissions before the function returns without blocking the execution of other code. When permissions are insufficient, the browser can request permissions from the user during the Promise waiting phase.
In order to avoid malicious sites to abuse the API to write malicious files, the user’s computer window. ChooseFileSystemEntries () function call must be in a secure page, active triggered by the user, is must in the callback of user interaction (such as a button click event), This is similar to input type=”file”.
Browsers may restrict access to some operating system-specific folders for protection purposes. And the browser notifies the site when it tries to write a file to a local folder.
To avoid frequent pop-up permissions warnings, the browser will save the permissions granted by the user, and once the user grants a page access to a file, the page will have the permissions until it is closed.
Once the page is closed, all permissions are taken back, and the next time a user visits the same site, the site needs to apply for permission again.
In the future, web pages could store authorization information in a built-in database (IndexedDB) to persist permission requests.
conclusion
As of now, the API has not been developed, and the standard is still subject to modification or deletion. However, the emergence of this API undoubtedly provides the possibility for the development of WebIDE. In the future, it may be possible to open the local project directory in the web page directly, edit and save the code, and directly use the online virtualization environment to execute the code test.
However, it remains to be seen whether the introduction of this API will cause serious security problems, because for the majority of users, security warnings are often ignored. It’s not that they don’t care, it’s that they don’t understand.
For example, even if the HTTPS configuration of a website is wrong and the warning of possible risks is displayed, users still habitually choose “advanced” – “Continue to enter”; Hence the HSTS, which prevents users from continuing to use a website if an HTTPS error occurs.
Thus, even if the browser clearly indicates that you have security problems, users still selectively ignore them. Therefore, the permission application provided by Native File System API is only displayed as a “prompt box”, which is “ignored” by the majority of ordinary users and can be directly determined without thinking.
If a user visits a malicious site, a permission request, once “OK” is clicked, the data on the entire hard drive is encrypted…
Safety, and convenience, or need a balance!
Emmmm… Is that off topic…
Wicg.github. IO /native file…
A plain text editor Chrome lab Demo: googlechromelabs. Making. IO/text – editor…