Introduction

In the previous chapter we got some intuition behind the File interface and how it's used to provide us with information about a selected file.

In this chapter we shall consider the parent class of this interface i.e Blob and see how to use blob objects in our applications, as a superset of File to operate raw file-like data on the go.

What is a blob?

Essentially:

A blob is an object in JavaScript that represents raw file-like data.

Unlike a buffer, a blob is a broader and more capable interface not just used to store binary data (as is a buffer), but also used in various other interfaces such as FileReader().

The name 'blob' stands for Binary Large Object and has its origins in the database languages' world.

Appreciate the fact that the name 'blob' well describes the underlying concept i.e a blob is a large object in binary format.

A blob doesn't always have to be a large binary object - sometimes it can be small too! However, usually, it isn't.

But what's the point of having a blob?

The reason behind the idea of blobs in JavaScript was to allow developers a way to easily work with raw data and use it in place of actual files.

For example, processing an image file sent using AJAX, or generating a file-like object dynamically.

The File interface was sensibly taken to represent only direct files on the local filesystem - we select a file, the browser generates a File object out of it and finally we use this object for various things such as reading it using FileReader() and so on.

The Blob interface was taken to be a general case i.e it could be used to represent file-like objects as well.

Being able to use file-functionality in the language shouldn't just be limited to real files - we should also be able to use the same functionality on dynamically created file-like objects.

We're using the term 'file-like object' here, to emphasize on the fact that we're not referring to actual files on the local filesystem, but rather to an object that resembles the attributes of an actual file.

So what we shall understand from the discussion above is that:

A blob is used to represent any file-like data; the data can be obtained from an actual file OR it can be obtained from a file-like object.

Following from this, the File interface inherits from Blob, and is used to represent actual files (selected using the ways discussed in File APIs - File Object).

For the latter, i.e representing a file-like object, we've got the Blob interface itself.

Now that we've got some solid explanation on the concept of blobs in JavaScript, we can proceed onwards to see how to create one?

Syntax of creating a blob

Creating a blob is very simple - just use the Blob() constructor.

Shown below is the general form of the constructor:

new Blob(blobParts [, options]);

The first blobParts argument is an array of string, ArrayBuffer or Blob objects. It's the actual data of the blob. Omitting it will create an empty blob.

The second options argument is an object configuring the blob, with two further properties:

  1. type - a string to indicate the MIME type of the data. This property basically hints the blob of the underlying data - if it's specified the blob can easily parse the data, otherwise it may produce unexpected results.
  2. endings to indicate how line endings shall be treated within blobParts. Note that this property isn't frequently used.

Since the property type requires the developer to know a bit about MIME types, following we've compiled a list of the most common of them.

MIME typeDescription
text/plainPlain text document
text/htmlHTML document
text/javascriptJavaScript file
text/cssCSS file
application/jsonJSON file
application/pdfPDF file
application/xmlXML file
image/jpegJPEG image
image/pngPNG image
image/gifGIF image
image/svg+xmlSVG image
audio/mpegMP3 file
video/mpegMP4 file
The MIME types shown here will go in the property type as a string. For example text/plain will be written as "text/plain".

With the syntax well set, let's now incorporate all this with the essence of a real example.

Creating a blob

We'll dynamically create a simple, plain text file with the content "Hello World", using Blob().

var blob = new Blob(["Hello World"], {type: "text/plain"});

Let's dissect this code:

First the Blob() constructor is called, as usual with the new keyword.

Then, as the first argument, we pass an array containing just one string.

Regardless of whatever data you want to put in a blob, it has to be wrapped up in an array. This is because the internal engine iterates through the array and lines up the raw data of each item next to one another.

Afterwards, as the second argument, we pass an object with type set to "text/plain" to hint the blob that the underlying data is to represent a plain text file.

With this done we can now interact with the blob object and retrieve its properties.

A Blob object essentially has two properties:

  1. size - the size of the underlying data, in bytes.
  2. type - the MIME type of the blob.

For our blob object above, can you determine the values of both these properties?

Remember that the string "Hello World" is UTF-8 encoded and hence each of its characters take up 1 byte!

Let's see it in real:

var blob = new Blob(["Hello World"], {type: "text/plain"});

console.log(blob.size); // 11
console.log(blob.type); // "text/plain"

As you can see, blob.size returns 11, which is synonymous with the length of the string "Hello World".

Furthermore, blob.type returns the same type value we sent within the options object, when creating the blob i.e "text/plain".

In fact, type returns whatever value you assigned to the same property in the options parameter of the Blob() constructor.

Now just constructing a blob isn't very useful - we need to utilise it somewhere, of which the most sound option is to create an object URL out of it. Following we do just this very thing.

For a detailed guide to object URLs please read JavaScript Object URLs.
<iframe></iframe>
var iframe = document.getElementsByTagName("iframe")[0];

var blob = new Blob(["Hello World"], {type: "text/plain"});

// create an object URL for the blob constructed above
iframe.src = URL.createObjectURL(blob);

Live Example

Slicing a blob

Besides employing the Blob() constructor to create a over-fresh blob, one can also create a blob out of a blob. We refer to this as slicing a blob.

Slicing blobs is much like slicing arrays - we provide a starting point and an ending point, and consequently the object is sliced around both those points.

The question is: how do we slice a blob?

Well, once again, it's just like how we slice arrays i.e using the slice() method.

The slice() method, inherited by blobs from Blob.prototype, takes three optional arguments and returns a new blob meeting the criteria set by those arguments.

blob.slice([start,[ end[, contentType]]]);

The arguments work as follows:

  1. The first parameter start, sets the starting point of the slice i.e it tells where the slicing should begin. The default value is 0, which means that the slicing should begin right from the first byte.
  2. The second parameter end, sets the ending point of the slice. It is exclusive, which means that slicing won't be done upto that point, but rather just before it. The default value is the size of the blob.
  3. The third and last contentType parameter sets the MIME type of the new blob. If omitted, it defaults to the original type of the blob.
The first two parameters of slice() can also be given negative values. If this happens, then the offsets begin from the end of the blob, instead of from the start. We'll see an example below.

Let's consider an example.

Following, we slice a blob from the "Hello World" blob, we created above, create an object URL for it and finally assign this to the iframe's src:

var iframe = document.getElementsByTagName("iframe")[0];

var blob = new Blob(["Hello World"], {type: "text/plain"});

// create a new blob by slicing the blob above
// from bytes 0 to 9
var subBlob = blob.slice(0, 10);

// create an object URL for the blob constructed above
iframe.src = URL.createObjectURL(subBlob);

Live Example

As expected, the content of subBlob reduces down to "Hello Worl" since we've omitted the last byte in slicing blob.