简体   繁体   中英

Creating and downloading text file from string in JavaScript: Blob/createObjectURL vs. encodeURIComponent

As I've been looking for a way to create and download a text file from a website with JavaScript, I've found a bunch of solutions but generally using either Blob / createObjectURL or otherwise encodeURIComponent , with the former being more popular from what I've seen. Below I show two examples: note that only one-two lines in the beginning are different in the two functions (which I noted in comments).

Blob / createObjectURL :

function dl_as_file_Blob(filename_to_dl, data_to_dl) {
    let blobx = new Blob([data_to_dl], { type: 'text/plain' }); // ! Blob
    let elemx = window.document.createElement('a');
    elemx.href = window.URL.createObjectURL(blobx); // ! createObjectURL
    elemx.download = filename_to_dl;
    elemx.style.display = 'none';
    document.body.appendChild(elemx);
    elemx.click();
    document.body.removeChild(elemx);
}

encodeURIComponent :

function dl_as_file_URI(filename_to_dl, data_to_dl) {
    let elemx = document.createElement('a');
    elemx.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(data_to_dl); // ! encodeURIComponent
    elemx.download = filename_to_dl;
    elemx.style.display = 'none';
    document.body.appendChild(elemx);
    elemx.click();
    document.body.removeChild(elemx);
}

What I'd like to know is whether there is any reason to prefer one over the other. So far I could find two small differences. First, encodeURIComponent is more widely supported by browsers than createObjectURL . Second, Blob seems not to support encoding . Based on this, I'd choose the encodeURIComponent solution, but I wonder if there is a reason for why I see the Blob / createObjectURL solution more often.

EDIT : The question above is quite general, so let me narrow down a bit for my specific use case: I want to allow users to download a simple (utf-8), relatively small (max 100-200 kB) text (the results of a completed self-assessment test). There is no really sensitive data involved, and the file is only needed for this purpose alone, on the client-side. Nonetheless, I also welcome more general answers, since I'm curious about the differences.

I wonder if there is a reason for why I see the Blob/createObjectURL solution more often.

IMHO there are a few possible reasons:

TL;DR

  1. Performance

  2. Security

  3. API access

  4. It is an object

  5. It looks cooler


1. Performance

  • You have full control of the content.

  • You can store and access very large amount of data: very fast (async, worker threads) to/from the Web, the local filesystem, local databases, and also other windows and workers.

  • You can store Objects in a performant way.

  • Content can be accessed as text, as typed arrays, or as URLs.

  • You can splitt stored data: for better performance results (gains are like static lenght arrays vs dynamic ones).

  • Blob s you can store in memory or on disks.

  • Blob s can be read from and written to/from the Web, the local.

  • Garbage collection.

Most importantly, client-side JavaScript File object is a subtype of Blob , a File is just a Blob of data: with a name and a modification date. You can obtain File objects from <input type="file"> elements and from the drag-and-drop API.

2. Security

  • You have full control of the content. (at least for now)

  • CORS: Blob is same origin, while data: has to be specified in the cors rules, btw data: can be used to be/do evil things.

  • You can do even much more evil things with data: , but this should not be posted/discussed here.

3. API access

Once you have a Blob , there are various things you can do with it, many of them symmetrical to the items above:

  • You can send a Blob to another window or worker thread with postMessage().

  • You can store a Blob in a client-side database.

  • You can upload a Blob to a server by passing it to the send() method of an XMLHttpRequest object. (remember, a File object is just a specialized kind of Blob ).

  • You can use the createObjectURL() function to obtain a special blob:// URL that refers to the content of a `Blob, and then use this URL with the DOM or with CSS.

  • You can use a FileReader object to asynchronously (or synchronously, in a worker thread) extract the content of a Blob into a string or ArrayBuffer.

  • You can use the Filesystem API and the FileWriter object to write a Blob into a local file.

4. It is an object

  • I think, i don't need to enter this discussion:D

5. It looks cooler

  • A short Blob URL looks much better than for example a 4096 kB string.

  • You can do much more cool stuff with Blob .

sources:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM