
In web development, handling binary data has become a daily task. Whether it's file uploads, image processing, or data exchange with servers, binary data plays a crucial role. The Blob object in JavaScript is one of the core tools for managing such data.
A Blob (Binary Large Object) is an immutable object in JavaScript that represents binary data. It can contain various types of data, such as text, images, audio, video, etc., meaning that a Blob does not necessarily represent data in JavaScript's native format.
The Blob object is commonly used for handling file data, especially in scenarios like file uploads, downloads, and data processing. The File object, which is a subclass of Blob, is often the main participant in these tasks.
A Blob object consists of two parts:
text/plain, image/png, etc.MIME (Multipurpose Internet Mail Extensions) was originally designed to address the issue of transmitting non-text data in emails. Early email systems could only transmit plain text, which limited their ability to handle multimedia data like images, audio, and video. MIME was created to solve this problem.
MIME defines a standard format for describing data types and encoding methods, enabling email systems to transmit various types of data. As the internet evolved, MIME's applications expanded, becoming a standard for describing data types in web development.
A MIME type consists of two parts: a main type and a subtype, separated by a slash (
/). For example,text/plainrepresents plain text data, whileimage/pngrepresents PNG image data.
It's worth noting that a Blob object can exist either in memory or on disk, depending on how you obtain it. If you use an input interface to get a file from disk, the data resides on disk because users might upload files as large as several GB, which cannot be entirely loaded into memory.
In JavaScript, you can create a Blob object using the Blob constructor. The Blob constructor takes two parameters:
Array, containing ArrayBuffer, TypedArray, DataView, Blob, strings, or a mix of these elements, which will be placed into the Blob.type property to set the Blob's MIME type.const data = ["Hello, world!"];
const blob = new Blob(data, { type: 'text/plain' });
console.log(blob); // Blob { size: 13, type: 'text/plain' }In the example above, we created a Blob object containing text data and specified its MIME type as text/plain.
At this point, the object resides in memory.
size: Returns the size of the data in the Blob object in bytes.type: Returns the MIME type of the Blob object.console.log(blob.size); // 13
console.log(blob.type); // 'text/plain'slice(start, end, contentType): Creates a new Blob object containing the specified range of data from the original Blob. The start and end parameters define the range, and contentType specifies the MIME type of the new Blob.const slicedBlob = blob.slice(0, 5, 'text/plain');
console.log(slicedBlob); // Blob { size: 5, type: 'text/plain' }arrayBuffer(): Returns a Promise that resolves to an ArrayBuffer containing the binary data of the Blob.blob.arrayBuffer().then(buffer => {
console.log(new Uint8Array(buffer)); // Uint8Array(13) [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
});text(): Returns a Promise that resolves to a string containing the text data of the Blob.blob.text().then(text => {
console.log(text); // 'Hello, world!'
});stream(): Returns a ReadableStream object, allowing you to read the data in the Blob as a stream. This is useful for handling large files or scenarios where data needs to be processed in chunks.const stream = blob.stream();
const reader = stream.getReader();
reader.read().then(function processText({ done, value }) {
if (done) {
console.log('Stream complete');
return;
}
console.log(new Uint8Array(value));
return reader.read().then(processText);
});The Blob object provides multiple ways to read its content, primarily divided into modern and traditional methods. Modern methods are based on Promise, making them more concise and easier to use, while traditional methods rely on the FileReader API, which is suitable for scenarios requiring finer control.
| Feature | Modern Methods (text(), arrayBuffer(), stream()) | Traditional Methods (FileReader) |
|---|---|---|
| Ease of Use | Based on Promise, code is concise | Based on event callbacks, code is slightly more complex |
| Performance | Efficient, suitable for modern browsers | Better compatibility, slightly lower performance |
| Use Cases | Suitable for quickly reading small files or simple data processing | Suitable for large files or scenarios requiring incremental processing |
| Streaming Support | Supported (stream()) | Not supported |
| Compatibility | Supported by modern browsers | Better compatibility, supports older browsers |
Modern methods are suitable for quickly reading small files or simple data processing, while traditional methods are better for handling large files or scenarios requiring incremental reading.
In file upload scenarios, the Blob object is often used to handle user-selected files. Using the FileReader or fetch API, files can be read as Blob objects and then uploaded to the server.
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function(event) {
const file = event.target.files[0];
const formData = new FormData();
formData.append('file', file);
fetch('/upload', {
method: 'POST',
body: formData
}).then(response => {
console.log('File uploaded successfully');
});
});Here, the Blob object isn't explicitly visible, but you can understand that the file itself is a File object, which is a subclass of Blob. Therefore, a Blob object is being attached to the POST HTTP request. The FormData object allows you to attach files or other data to an HTTP request and send it to the server via the fetch API.
The Blob object can also be used to generate and download files. By creating a Blob object containing data and using URL.createObjectURL to generate a URL, you can set this URL as the href attribute of an <a> tag to enable file downloads.
const data = ["Hello, world!"];
const blob = new Blob(data, { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt';
a.click();
URL.revokeObjectURL(url); // Release the URL objectThe URL.createObjectURL method is interesting because it creates a URL in the browser's memory that points to the Blob object. This URL typically follows the format blob:domain/unique-identifier, such as blob:https://example.com/550e8400-e29b-41d4-a716-446655440000.
The browser maps this URL to the Blob object in memory, and when you access this URL, the browser returns the corresponding Blob content. This allows us to handle Blob data like a regular URL, such as using it in the src attribute of an img tag or for file downloads as shown above.
It's important to note that when the URL is no longer needed, you should call URL.revokeObjectURL() to release it; otherwise, it will remain in memory until the page is closed.
In image processing scenarios, the Blob object can be used to convert image data into a Blob for further processing or uploading.
const canvas = document.querySelector('canvas');
canvas.toBlob(function(blob) {
const formData = new FormData();
formData.append('image', blob);
fetch('/upload-image', {
method: 'POST',
body: formData
}).then(response => {
console.log('Image uploaded successfully');
});
}, 'image/png');The Blob object can also be used for converting between various data formats. For example, you can convert JSON data into a Blob:
const jsonData = { name: 'John', age: 30 };
const jsonString = JSON.stringify(jsonData);
const jsonBlob = new Blob([jsonString], { type: 'application/json' });
// You can then send this Blob to the server or save it as a fileOr convert Base64-encoded data into a Blob:
function base64ToBlob(base64, mimeType) {
// Remove the data URL prefix (e.g., data:image/png;base64,)
const byteString = atob(base64.split(',')[1]);
// Create an ArrayBuffer containing the byte array
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: mimeType });
}
// Usage example
const base64Image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...';
const imageBlob = base64ToBlob(base64Image, 'image/png');The Blob object is also widely used in audio and video processing. For example, you can use the MediaRecorder API to record audio or video and save the result as a Blob:
// Assuming a media stream has been obtained
const mediaRecorder = new...