JavaScript is one of the most popular programming languages around primarily because it handles the front-end of websites while running inside a browser. With the advancements in web standards, we have been increasingly using it to accomplish more and more tasks that were earlier either very difficult or impossible to do with just JavaScript.
In this tutorial, you will learn how to create and save files with JavaScript. We will discuss three different techniques that you can use to do so.
Using Data URLs to Save Files
The easiest way to save a file is to use Data URLs that include all the relevant information. These data URLs are special URLs that are prefixed with the data:
scheme. They are ideal for embedding small files in your HTML documents. These URLs follow the following syntax:
data:[<mediatype>][;base64],<data>
The mediatype
token is actually a MIME type that specifies the nature and format of a document or file. Its default value is text/plain;charset=US-ASCII
. The base64
token is optional and needed only when you want to store binary data textually. We specify our actual data after all these tokens.
We can use the download
attribute to specify the name of the file where we want to put all our content after download. Here is an example of using all these attributes together:
<a download="monty.txt" href="data:text/plain;charset=utf-8,My name is Monty.">Download Text File with Name</a>
JavaScript can be very handy when you want to make the whole thing dynamic. Here is an example:
const link = document.querySelector('a.dynamic'); let name = 'Monty'; let text = `My name in ${name}. I love writing tutorials.`; link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); link.setAttribute('download', `${name.toLowerCase()}.txt`);
We begin by selecting our link using the querySelector()
method and then create a bunch of variables to store the file name and its contents. Use of template literals allows us to work with multi-line strings easily.
We create our data URL by concatenating the meta data with the actual content encoded using the encodeURIComponent()
function. The following CodePen demo shows this method of saving text files using JavaScript.
Using Blobs to Create and Save Files
Blobs are file-like objects in JavaScript which contain raw data. This raw data can be read either as text or as binary data. In this tutorial, we will use blobs to create and save files in JavaScript.
We can create our own blobs using the Blob()
constructor which accepts an array of specific objects to be put inside the blob. You can pass the MIME type of the data as key-value pair in an object that is the second parameter of the Blob()
constructor. It is an empty string by default.
We could modify the last example in our previous section to use blobs with the following JavaScript code:
const link = document.querySelector('a.simple'); let name = 'Monty'; let text = `My name in ${name}. I love writing tutorials.`; var textBlob = new Blob([text], {type: 'text/plain'}); link.setAttribute('href', URL.createObjectURL(textBlob)); link.setAttribute('download', `${name.toLowerCase()}.txt`);
We create our textBlob
by calling the Blob()
constructor and passing our text
variable to it as an array element. After that, we simply set the value of href
and download
attributes. The URL in this case is created by calling the createObjectURL()
function which returns a string that contains the URL for the object that we passed to it.
Lets go a step further and create a blob where the text is obtained dynamically from a textarea
element on the webpage. You will be able to write anything you like in the textarea
and then click on the Save File button to save it as a file.
const saveBtn = document.querySelector('button.save-file'); let name = 'Monty'; saveBtn.addEventListener('click', function(){ var tempLink = document.createElement("a"); let textArea = document.querySelector("textarea"); var taBlob = new Blob([textArea.value], {type: 'text/plain'}); tempLink.setAttribute('href', URL.createObjectURL(taBlob)); tempLink.setAttribute('download', `${name.toLowerCase()}.txt`); tempLink.click(); URL.revokeObjectURL(tempLink.href); });
We begin by getting a reference to our button and then listening to its click events. Once the button is clicked, we get the value of our textarea
element and convert it to a blob. After that, we create a URL that references our blob and assign it to the href
attribute of the anchor tag that we created.
You can try it out in the following CodePen demo. As an exercise, try to modify the code so that that it saves the file with a name entered by the users instead of something static.
How to Save File in a Specific Folder Using JavaScript?
Lets begin by getting this question out of our way first. In short, it is not possible for you to arbitrarily choose the directory where a file is saved in JavaScript. Only the user has control over the location where a file is saved.
The reason a web developer is not allowed to have complete control over the location where a file is saved by the browser has to do with security. The internet would be a lot less secure if every website had access to the filesystem on your device. They could simply inject malicious code into your system or view private information.
Earlier, it wasn't possible to save a file anywhere except the default download folder which was dictated by the browser's setting and not individual websites. However, the File System Access API allows developers to suggest where a file can be saved after they have been granted access by the user. Keep in mind that the wider browser support is currently lacking for the API and the browsers which do support it only do it partially.
Lets modify our last example from the previous section to create and save a file in JavaScript with the File System Access API.
const saveBtn = document.querySelector('button.save-file'); let name = 'Monty'; saveBtn.addEventListener('click', async function(){ let textArea = document.querySelector("textarea"); var taBlob = new Blob([textArea.value], {type: 'text/plain'}); const pickerOptions = { suggestedName: `${name.toLowerCase()}.txt`, types: [ { description: 'Simple Text File', accept: { 'text/plain': ['.txt'], }, }, ], }; const fileHandle = await window.showSaveFilePicker(pickerOptions); const writableFileStream = await fileHandle.createWritable(); await writableFileStream.write(taBlob); await writableFileStream.close(); });
As usual, we begin by creating a blob of the text
inside the textarea
element. We create an object that contains different options for our file picker that shows up when we call the showFilePicker()
method. We can suggest a name to save the file here and also pass an array of allowed file types to save. This method returns a FileSystemFileHandle
on which we can call the createWritable()
method.
The createWritable()
method creates a writable stream and we write the blob we created earlier to this stream. Finally, we close our writable stream. At this point, the content from the stream is saved to the file.
Try writing something in the textarea
of the following CodePen and then click on the Save File button. The demo will not work in Firefox so you should try using Chrome or Edge.
Final Thoughts
In this tutorial, we learned three different techniques of creating and saving files in JavaScript. The first two techniques require us to create anchor tags and assign values to their href
and download
attributes. The last technique involves use of the File System Access API and gives us better control over different aspects of the process like changing the default download location with user's permission. However, it doesn't currently have significant browser support to be used in real projects.
No comments:
Post a Comment