Being able to access the content of the files uploaded in a web page, or what is the same, allowing the reading of the files uploaded in the web application through a native JavaScript API opens up a huge amount of possibilities for the creation of web applications for the file management and editing.
Plain text files can be loaded to edit the text that composes it, validate the content, show previews, etc. and all this from the client side without the need to connect to another server.
Earlier we explained the different properties that exist in the file API in JavaScript to get data from files; now we will go a little further to arrive at its opening for a later reading of the files loaded by means of input type="file" or other methods such as Drag and Drop.
1.0 Checking browser compatibility
First of all, and like any new technology, it is recommended to verify that the browser supports using the API; The File interface should be referenced instead of the FileList interface which provides read-only file data such as its name and more importantly its content.
To verify compatibility we can use the following JavaScript code:
if (!(window.File)) { console.log('La API File no está soportada'); return; }
Guaranteed support of the file API (window.File) by the browser, now it is possible to use the different methods and properties that the file API has to read it.
2.0 Getting User Files
The most common method of getting files by the user is through the input type="file" tag; although any API that returns the list of files will work and the content of these will be accessed with the file API like the Drag and Drop experiment that we saw previously.
It is possible to obtain multiple information about the list of files that were currently loaded (supports the multiples attribute).
3.0 the FileReader interface for reading files
This interface provides us with methods for reading files such as:
- FileReader.readAsBinaryString(Blob|File): The file or blob must be specified, the result property will contain the data of the file/BLOB object in the form of a binary string. Each byte is represented by an integer between 0 and 0.255, inclusive.
- FileReader.readAsText(Blob|File, [opt_encoding]): You must specify the file or blob and optionally the encoding that is UTF-8 by default; the file must be plain text.
- FileReader.readAsDataURL(Blob|File): The file or blob must be specified and the content must be base64 encoded.
All these methods have in common the passing of the file as parameters to be able to access its content, once its content is accessed and the content is read, the loadend event is triggered.
Although for the examples presented (which are assumed to be plain text) it would be useful to use any of the methods seen above, although some return the MIME among other things.
If you want more information, feel free to consult the MDN: FileReader.
3.1 FileReader interface events
The loadend event is fired after the file read is successful and from here you can access the contents of the file and do something with it.
Reading captured files using an input type="file"
The most basic or common use that we can think of is to capture the file selected by an input type="file" and display its content:
var MAX_BYTES = 102400; // 100 KB
function filesInfo(event) {
if (!(window.File)) {
console.log('La API File no está soportada');
return;
}
var file;
var reader;
var files = document.getElementById('files').files;
for (var i = 0; i < files.length; i++) {
file = files[i];
reader = new FileReader();
reader.onloadend = onFileLoaded;
reader.readAsBinaryString(file);
}
}
function onFileLoaded(event) {
document.getElementById("resultado").innerHTML = event.currentTarget.result.substr(0, MAX_BYTES);
}
We see that the structure is similar to the ones seen in the previous post: except that now we use the FileReader method to read the files and the subsequent call of the onloadend event when reading is finished; finally the experiment:
Reading Captured Files Using Drag and Drop
The last example consists of adapting the experiment seen previously with the Drag and Drop using all the events of the Drag and Drop until the capture of the file in the drop() event:
var MAX_BYTES = 102400; // 100 KB
function dragenter(event) {
event.stopPropagation();
event.preventDefault();
}
function dragover(event) {
event.stopPropagation();
event.preventDefault();
}
function drop(event) {
console.log('drop', event);
event.stopPropagation();
event.preventDefault();
var data = event.dataTransfer;
var files = data.files;
var file;
var reader;
for (var i = 0; i < files.length; i++) {
file = files[i];
reader = new FileReader();
reader.onloadend = onFileLoaded;
reader.readAsText(file);
}
}
function onFileLoaded(event) {
document.getElementById("resultado").value = event.currentTarget.result.substr(0, MAX_BYTES);
}
var contenedor = document.getElementById("contenedor");
contenedor.addEventListener("dragenter", dragenter, false);
contenedor.addEventListener("dragover", dragover, false);
contenedor.addEventListener("drop", drop, false);
Other links of interest
Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter