Html5's File API - BLOB usages?

27,765

Solution 1

The length of a blob: URL is always below a reasonable limit.

Data URLs can be arbitrary large. Consequently, when a data URL is too long, some browsers (IE, cough) will not display the image any more. So, if you want to display very large files, using blob: (or filesystem: URLs) might make more sense than data-URLs.


Also, you can directly recover data from a blob: URL (provided that the blob has not been revoked yet, e.g. because the document was unloaded, and the same origin policy is not violated) using XMLHttpRequest. For example, the following code gets the content of a blob URL as text:

var blobUrl = URL.createObjectURL(new Blob(['Test'], {type: 'text/plain'}));
var x = new XMLHttpRequest();
// set x.responseType = 'blob' if you want to get a Blob object:
// x.responseType = 'blob';
x.onload = function() {
    alert(x.responseText);
};
x.open('get', blobUrl);
x.send();

If you want to submit the contents of a File to a server using XMLHttpRequest, it doesn't really make sense to use a blob: or data: URL. Just submit the File object directly using the FormData object. If you lost the original File reference, and you only have a blob: URL, then you can use the previous snippet to get a Blob object again for use in FormData.

Given a data:-URL, it is far from easy to recover the original data. Firefox and Opera 12- allow use of a data:-URL in XMLHttpRequest. Chrome, Internet Explorer, Safari and Opera 15+ refuse to load a data-URL via XMLHttpRequest. So, with respect to recovering data, blob: URLs are also superior over data:-URLs.

If you want to display the result of a File in a different frame on the same origin, definitely use a blob: URL. If you want to manipulate data contained in a Blob in a differerent frame (possibly on a different origin), do not use blob or data URLs, send the data directly using postMessage.

blob:-URLs are generally better than data:-URLs for representing (binary) data. For small data (max 20kb), data: URLs might be a better choice because of the higher range of supported browsers: Compare Can I use Blob URLs with Can I use Data URIs (though if you're writing a complex HTML5 application, odds are that you're not going to support IE9-).

Solution 2

Here's the main differences in how you can use the two types of URLs:

Data URLs:

Pros:

  • you can get data out of them very easily
  • you can send them to another user or across HTTP, and the data's still there
  • It doesn't matter where or how they were created, if the data is valid, you'll see the content in any browser, on any OS, anywhere

Cons:

  • Data URLs are often prohibitively long, so that IE might not be able to handle them and it can get annoying to handle in any browser
  • They are less efficient than BLOB URLs (you have to read the file to create it, you don't with BLOBs, etc)

BLOB URLs:

Pros:

  • They are much shorter than Data URLs, making them far more manageable
  • you can access their data, but since the URL is only an opaque reference to the data, the data must be accessed using a FileReader and the data cannot be extracted directly from the URL, as in Data URLs
  • because they have a reasonable length, they are easier to deal with and have better IE support

Cons:

  • The data isn't accessible in the URL itself (the URL is an opaque reference) and it isn't stored in the cloud
  • Because of con #1, you can't send the URL to the server/a different user, as they will be unable to access the data. So the URL's only for you.
  • You also can't access the data from the BLOB URL in a different browser (even on the same machine)
  • Also, you are unable to access a BLOB URL from a different origin, even on the same browser

This list makes it seem like data URLs are an obvious advantage, but BLOB urls are faster to create, and, unless you need to send the url to other users or to the server, you should use them because they are faster, easier to use, more manageable, and better for IE. But if you do need to send a url to the server or to another user, I would recommend somehow transmitting the blob directly using XHR2. Data urls aren't that great.

Share:
27,765

Related videos on Youtube

Royi Namir
Author by

Royi Namir

Updated on September 04, 2020

Comments

  • Royi Namir
    Royi Namir over 3 years

    I have a file input : (jsbin)

     <input type="file"   accept="image/*" id="input" multiple   onchange='handleFiles(this)' />
    

    Which, when file selected, shows small images of the selected image:

    I can do it in two ways :

    using FileReader:

    function handleFiles(t) //t=this
    {
        var fileList = t.files;
        for (var i = 0; i < fileList.length; i++)
        {
            var file = fileList[i];
            var img = document.createElement("img");
            img.style... = ...
            document.getElementById('body').appendChild(img);
            var reader = new FileReader();
            reader.onload = (function (aImg)
            {
                return function (e)
                {
                    aImg.src = e.target.result;
                };
            })(img);
            reader.readAsDataURL(file);
        }
        // ...
    }
    

    using ObjectURL / BLOB :

     function handleFiles(t)
     {
         var fileList = t.files;
         for (var i = 0; i < fileList.length; i++)
         {
             var file = fileList[i];
             var img = document.createElement("img");
             img.src = window.URL.createObjectURL(file);
             img.onload = function (e)
             {
                 window.URL.revokeObjectURL(this.src);
             }
             document.getElementById('body').appendChild(img);
         }
     }
    

    As you can see , both work :

    enter image description here

    BUT

    The html result is different :

    enter image description here

    Question :

    With the first one, I already know what I can do, it's pure data-uri data.

    But when should I use the second approach (blob)? I mean - what can I do blob:http%3A//run.jsbin.com/82b29cc5-8452-4ae2-80ca-a949898f4295 ?

    p.s. mdn explanation about URL.createObjectURL doesn't help me about when should I use each.

  • Rob W
    Rob W over 10 years
    I'm not convinced by your list of pros and cons. blob/data URLs are typically used for offering a file download to the user and/or displaying the data in a media element (e.g. <img>), not for transferring data to another website or page. To share data with other frames, you usually post the raw buffer itself. Serializing the blob as a data-URL is highly inefficient: FileReader is needed to convert a blob to a data-URL. If the receiver wants to use the data again, then parsing the URL manually (using atob and string manipulation functions) is the worst way of getting a blob back. [...]
  • Rob W
    Rob W over 10 years
    [...] To post the data to a server, you use the FormData object to send File/Blob objects with minimal overhead (contrary to data URLs, base64-encoding significantly increases data size). Since we both conclude that blob: URLs are generally the best choice in modern browsers, I will continue with your cons of blob URLs. As said before, you typically do not send URLs to other parties, but data. If you don't have the original data any more, XHR can be used to get a Blob again. Just like blob: URLs, data-URLs cannot be recovered through XHR either (IE, Chrome, Safari, Opera 15+).
  • Royi Namir
    Royi Namir over 10 years
    1) Does the blob address is transferable across iframes ? data-uri is transferable between anything. does the blob is transferable ? 2) how can i see the data (bytes) which is represented by the blob url ? 3) does the blob guid is time limited ? I mean , If i come back to the computer tomorrow , and I open the browser again , will the blob be valid ?
  • Rob W
    Rob W over 10 years
    @RoyiNamir 1. Yes, within the boundaries of the same-origin policy. Though if you want to transfer data between iframes, just use postMessage to transfer the file directly (no need to serialize the data!) 2. Use XMLHttpRequest to query the content of the blob:-URL. 3. No, the blob's lifetime is tied to a document, not time). It only disappears when the document is unloaded, or when URL.revokeObjectURL is used. See w3.org/TR/FileAPI/#url for extensive documentation on blob URLs.
  • Royi Namir
    Royi Namir over 10 years
    Regarding "2" : did you mean to upload it to the server and then investigate its data ?
  • Rob W
    Rob W over 10 years
    @RoyiNamir No. See my expandeded answer (in reply to your follow-up questions).
  • Royi Namir
    Royi Namir over 10 years
  • Kaiido
    Kaiido almost 7 years
    This is old, but one other big advantage of Blobs against dataURIs is the memory usage. In OPs example, he is handling Files which come from an user input. In this case, the blobURI that is being generated is actually an simple symlink to the file on the user's disk while dataURI requires to load the file in active memory, read it, convert it to a dataURI, store the dataURI in memory (and in DOM in OP's case), parse the dataURI in memory again, read it again and display.
  • dsi
    dsi over 2 years
    Are these two Urls are same origin , I observed CROSS ORIGIN with this but both are same domain and https protocol ? https://devenvurl and blob:https://devenvurl