banner
 Sayyiku

Sayyiku

Chaos is a ladder
telegram
twitter

Blob Url And Data Url

image

Blob#

What is Blob#

Blob (binary large object) is a "container" that can store binary files.

A Blob object represents an immutable, raw data file-like object. The File interface is based on Blob, inheriting its functionality and extending it to support files on the user's system. Frontend pages often use the input tag to select local files for upload, and the resulting file object is inherited from blob.

<input type="file" id="avatar" accept="image/png" @change="readFile" />
<!--
File {
  lastModified: 1557995456923
  lastModifiedDate: Thu May 16 2019 15:30:56 GMT+0700 (GMT+07:00) {}
  name: "5c14f38ccd4fd.jpg"
  size: 7958
  type: "image/jpeg"
  webkitRelativePath: ""
}
-->

Some methods and properties of Blob:

  • Blob(blobParts[, options]): Constructor that returns a newly created Blob object whose contents are composed of the array concatenated from the parameters.
  • Blob.size: The size (in bytes) of the data contained in the Blob object.
  • Blob.type: A string indicating the MIME type of the data contained in the Blob object. If the type is unknown, this value is an empty string.
  • Blob.slice([start,[ end ,[contentType]]]): Returns a new Blob object containing the data in the specified range from the source Blob object, similar to the slice method of arrays.
const obj = { hello: 'world' }
const blob = new Blob([JSON.stringify(obj, null, 2)], { type: 'application/json' })
// Blob {size: 22, type: "application/json"}

The File object is a special type of Blob and can be used in any context where Blob types are applicable. For example, FileReader, URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send() can all handle Blob and File.

Function of Blob#

Using Blob allows you to generate a temporary file in the browser, and using URL.createObjectURL() to obtain its link, i.e., blob url, you can use it like a server file.

const blob = new Blob(['chanshiyu'])
URL.createObjectURL(blob)
// "blob:http://localhost:9528/9afae43c-b849-49bf-aed6-fc876d743303"

After creating this temporary file, as long as the current page is not closed, this file will remain in memory. You need to actively run URL.revokeObjectURL(url) to delete the reference.

The canvas provides the toBlob method to convert it to a blob:

// Use callback to get blob
canvasElem.toBlob(blob => {
  // blob ready, download it
  let link = document.createElement('a')
  link.download = 'example.png'

  link.href = URL.createObjectURL(blob)
  link.click()

  // delete the internal blob reference, to let the browser clear memory from it
  URL.revokeObjectURL(link.href)
}, 'image/png')

// Or use async to get blob
const blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'))

Many methods mentioned above can handle both File and Blob objects. With FileReader, you can read a Blob as a Buffer.

const blob = new Blob(['chanshiyu'])
const reader = new FileReader()
reader.addEventListener('loadend', () => {
  console.log('reader.result:', reader.result)
  /**
   * reader.result contains the blob converted to a typed array
   * ArrayBuffer(9)
   * [[Int8Array]]: Int8Array(9) [99, 104, 97, 110, 115, 104, 105, 121, 117]
   * [[Uint8Array]]: Uint8Array(9) [99, 104, 97, 110, 115, 104, 105, 121, 117]
   * byteLength: 9
   */
})
reader.readAsArrayBuffer(blob)

ArrayBuffer#

The design of ArrayBuffer is related to WebGL, which refers to the communication interface between the browser and the graphics card. To meet the large and real-time data exchange between JavaScript and the graphics card, data is transmitted through ArrayBuffer binary streams.

ArrayBuffer objects, TypedArray views, and DataView views are an interface for JavaScript to manipulate binary data. The ArrayBuffer object represents raw binary data, the TypedArray view is used to read and write simple types of binary data, and the DataView view is used to read and write complex types of binary data.

The TypedArray view supports a total of 9 data types, while the DataView view supports 8 types excluding Uint8C.

Data Type Byte Length Meaning
Int8 1 8-bit signed integer
Uint8 1 8-bit unsigned integer
Uint8C 1 8-bit unsigned integer (automatically filters overflow)
Int16 2 16-bit signed integer
Uint16 2 16-bit unsigned integer
Int32 4 32-bit signed integer
Uint32 4 32-bit unsigned integer
Float32 4 32-bit floating point
Float64 8 64-bit double precision floating point

The ArrayBuffer object represents a segment of memory that stores binary data. It cannot be read or written directly, only through views (TypedArray views and DataView views) that interpret the binary data in a specified format.

ArrayBuffer is also a constructor that can allocate a contiguous memory area to store data. To read its contents, a view must be specified.

// Generates a 32-byte memory area, each byte's value defaults to 0
const buf = new ArrayBuffer(32)

// Specify DataView to read content
const dataView = new DataView(buf)
// Read 8 bits of binary data from the start as an unsigned 8-bit integer
dataView.getUint8(0) // 0

// Specify TypedArray to read content
const x1 = new Int32Array(buf)
x1[0] = 1
const x2 = new Uint8Array(buf)
x2[0] = 2
// Due to shared memory, modifying one view will affect the other view
// x1[0] = 2

Data Url#

Data URLs, which have the prefix data:, allow content creators to embed small files into documents. Data URLs consist of four parts: the prefix (data:), the MIME type indicating the data type, an optional base64 marker if not text, and the data itself: data:[<mediatype>][;base64],<data>.

mediatype is a string representing the MIME type, for example, image/jpeg indicates a JPEG image file. If omitted, the default value is text/plain;charset=US-ASCII.

If the data is of text type, you can directly embed the text; if it is binary data, you can base64 encode the data before embedding. Here are some examples:

  • data:,Hello%2C%20World!: Simple text/plain type data
  • data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D: Base64 encoded version of the previous example
  • data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E: An HTML document source code <h1>Hello, World</h1>
  • data:text/html,<script>alert('hi');</script>: An HTML document that executes a JavaScript alert

base64#

Base64 is a method of representing binary data using 64 printable characters. It converts every 3 8-bit characters into 4 6-bit characters (hence the name, since 2^6 = 64). Because it uses printable characters, there are no strange whitespace characters.

Since 3 characters become 4, it is clear that after base64 encoding, the size of the encoded object will become 4/3 of the original. If the bit count cannot be divided by 3, 1 or 2 bytes (8 or 16 bits) need to be added at the end, and the trailing 0s are represented by = instead of A, which is why some base64 encoded results have one or two equal signs at the end.

You can convert text to base64 encoding using FileReader:

const blob = new Blob(['chanshiyu'], { type: 'text/plain' })
const reader = new FileReader()
reader.addEventListener('loadend', () => {
  console.log('reader.result:', reader.result)
  /**
   * reader.result contains the blob converted to base64
   * data:text/plain;base64,Y2hhbnNoaXl1
   */
})
reader.readAsDataURL(blob)

For the same text file, we can use blob url or convert it to data url, but using blob url is more efficient.

Both ways of making an URL of a blob are usable. But usually URL.createObjectURL(blob) is simpler and faster.

Comparison of Blob url and Data Url#

Blob url:

  • No encoding needed, saving computational resources
  • Size will not change
  • Need to manually delete references when not in use
  • Link automatically invalidated when the page is closed

Data Url:

  • Requires encoding, and size increases by 4/3
  • Easy to delete
  • Link remains unchanged, can be saved for later use
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.