fixes
This commit is contained in:
parent
b0d39f8568
commit
e9ded79b03
3 changed files with 28 additions and 28 deletions
|
@ -1,10 +1,10 @@
|
|||
# Blob
|
||||
`Blob` # Blob
|
||||
|
||||
`ArrayBuffer` and views are a part of ECMA standard, a part of JavaScript.
|
||||
|
||||
In the browser, there are additional higher-level objects, described in [File API](https://www.w3.org/TR/FileAPI/), in particular `Blob`.
|
||||
|
||||
`Blob` consists of an optional string `type` (a MIME-type usually), plus `blobParts` -- a sequence of other `Blob` objects, strings and `BufferSources`.
|
||||
`Blob` consists of an optional string `type` (a MIME-type usually), plus `blobParts` -- a sequence of other `Blob` objects, strings and `BufferSource`.
|
||||
|
||||

|
||||
|
||||
|
@ -16,8 +16,8 @@ new Blob(blobParts, options);
|
|||
|
||||
- **`blobParts`** is an array of `Blob`/`BufferSource`/`String` values.
|
||||
- **`options`** optional object:
|
||||
- **`type`** -- blob type, usually MIME-type, e.g. `image/png`,
|
||||
- **`endings`** -- whether to transform end-of-line to make the blob correspond to current OS newlines (`\r\n` or `\n`). By default `"transparent"` (do nothing), but also can be `"native"` (transform).
|
||||
- **`type`** -- `Blob` type, usually MIME-type, e.g. `image/png`,
|
||||
- **`endings`** -- whether to transform end-of-line to make the `Blob` correspond to current OS newlines (`\r\n` or `\n`). By default `"transparent"` (do nothing), but also can be `"native"` (transform).
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -35,7 +35,7 @@ let blob = new Blob([hello, ' ', 'world'], {type: 'text/plain'});
|
|||
```
|
||||
|
||||
|
||||
We can extract blob slices with:
|
||||
We can extract `Blob` slices with:
|
||||
|
||||
```js
|
||||
blob.slice([byteStart], [byteEnd], [contentType]);
|
||||
|
@ -47,8 +47,8 @@ blob.slice([byteStart], [byteEnd], [contentType]);
|
|||
|
||||
The arguments are similar to `array.slice`, negative numbers are allowed too.
|
||||
|
||||
```smart header="Blobs are immutable"
|
||||
We can't change data directly in a blob, but we can slice parts of blobs, create new blobs from them, mix them into a new blob and so on.
|
||||
```smart header="`Blob` objects are immutable"
|
||||
We can't change data directly in a `Blob`, but we can slice parts of a `Blob`, create new `Blob` objects from them, mix them into a new `Blob` and so on.
|
||||
|
||||
This behavior is similar to JavaScript strings: we can't change a character in a string, but we can make a new corrected string.
|
||||
```
|
||||
|
@ -57,9 +57,9 @@ This behavior is similar to JavaScript strings: we can't change a character in a
|
|||
|
||||
A Blob can be easily used as an URL for `<a>`, `<img>` or other tags, to show its contents.
|
||||
|
||||
Thanks to `type`, we can also download/upload blobs, and it naturally becomes `Content-Type` in network requests.
|
||||
Thanks to `type`, we can also download/upload `Blob` objects, and the `type` naturally becomes `Content-Type` in network requests.
|
||||
|
||||
Let's start with a simple example. By clicking on a link you download a dynamically-generated blob with `hello world` contents as a file:
|
||||
Let's start with a simple example. By clicking on a link you download a dynamically-generated `Blob` with `hello world` contents as a file:
|
||||
|
||||
```html run
|
||||
<!-- download attribute forces the browser to download instead of navigating -->
|
||||
|
@ -74,7 +74,7 @@ link.href = URL.createObjectURL(blob);
|
|||
|
||||
We can also create a link dynamically in JavaScript and simulate a click by `link.click()`, then download starts automatically.
|
||||
|
||||
Here's the similar code that causes user to download the dynamicallly created Blob, without any HTML:
|
||||
Here's the similar code that causes user to download the dynamicallly created `Blob`, without any HTML:
|
||||
|
||||
```js run
|
||||
let link = document.createElement('a');
|
||||
|
@ -89,7 +89,7 @@ link.click();
|
|||
URL.revokeObjectURL(link.href);
|
||||
```
|
||||
|
||||
`URL.createObjectURL` takes a blob and creates an unique URL for it, in the form `blob:<origin>/<uuid>`.
|
||||
`URL.createObjectURL` takes a `Blob` and creates an unique URL for it, in the form `blob:<origin>/<uuid>`.
|
||||
|
||||
That's what the value of `link.href` looks like:
|
||||
|
||||
|
@ -97,25 +97,25 @@ That's what the value of `link.href` looks like:
|
|||
blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273
|
||||
```
|
||||
|
||||
The browser for each url generated by `URL.createObjectURL` stores an the url -> blob mapping internally. So such urls are short, but allow to access the blob.
|
||||
The browser for each URL generated by `URL.createObjectURL` stores an the URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`.
|
||||
|
||||
A generated url (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the blob in `<img>`, `<a>`, basically any other object that expects an url.
|
||||
A generated URL (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the `Blob` in `<img>`, `<a>`, basically any other object that expects an url.
|
||||
|
||||
There's a side-effect though. While there's an mapping for a blob, the blob itself resides in the memory. The browser can't free it.
|
||||
There's a side-effect though. While there's an mapping for a `Blob`, the `Blob` itself resides in the memory. The browser can't free it.
|
||||
|
||||
The mapping is automatically cleared on document unload, so blobs are freed then. But if an app is long-living, then that doesn't happen soon.
|
||||
The mapping is automatically cleared on document unload, so `Blob` o bjects are freed then. But if an app is long-living, then that doesn't happen soon.
|
||||
|
||||
**So if we create an URL, that blob will hang in memory, even if not needed any more.**
|
||||
**So if we create an URL, that `Blob` will hang in memory, even if not needed any more.**
|
||||
|
||||
`URL.revokeObjectURL(url)` removes the reference from the internal mapping, thus allowing the blob to be deleted (if there are no other references), and the memory to be freed.
|
||||
`URL.revokeObjectURL(url)` removes the reference from the internal mapping, thus allowing the `Blob` to be deleted (if there are no other references), and the memory to be freed.
|
||||
|
||||
In the last example, we intend the blob to be used only once, for instant downloading, so we call `URL.revokeObjectURL(link.href)` immediately.
|
||||
In the last example, we intend the `Blob` to be used only once, for instant downloading, so we call `URL.revokeObjectURL(link.href)` immediately.
|
||||
|
||||
In the previous example though, with the clickable HTML-link, we don't call `URL.revokeObjectURL(link.href)`, because that would make the blob url invalid. After the revocation, as the mapping is removed, the url doesn't work any more.
|
||||
In the previous example with the clickable HTML-link, we don't call `URL.revokeObjectURL(link.href)`, because that would make the `Blob` url invalid. After the revocation, as the mapping is removed, the URL doesn't work any more.
|
||||
|
||||
## Blob to base64
|
||||
|
||||
An alternative to `URL.createObjectURL` is to convert a blob into a base64-encoded string.
|
||||
An alternative to `URL.createObjectURL` is to convert a `Blob` into a base64-encoded string.
|
||||
|
||||
That encoding represents binary data as a string of ultra-safe "readable" characters with ASCII-codes from 0 to 64. And what's more important -- we can use this encoding in "data-urls".
|
||||
|
||||
|
@ -130,7 +130,7 @@ For instance, here's a smiley:
|
|||
The browser will decode the string and show the image: <img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
|
||||
|
||||
|
||||
To transform a blob into base64, we'll use the built-in `FileReader` object. It can read data from Blobs in multiple formats. In the [next chapter](info:file) we'll cover it more in-depth.
|
||||
To transform a `Blob` into base64, we'll use the built-in `FileReader` object. It can read data from Blobs in multiple formats. In the [next chapter](info:file) we'll cover it more in-depth.
|
||||
|
||||
Here's the demo of downloading a blob, now via base-64:
|
||||
|
||||
|
@ -151,23 +151,23 @@ reader.onload = function() {
|
|||
};
|
||||
```
|
||||
|
||||
Both ways of making an URL of a blob are usable. But usually `URL.createObjectURL(blob)` is simpler and faster.
|
||||
Both ways of making an URL of a `Blob` are usable. But usually `URL.createObjectURL(blob)` is simpler and faster.
|
||||
|
||||
```compare title-plus="URL.createObjectURL(blob)" title-minus="Blob to data url"
|
||||
+ We need to revoke them if care about memory.
|
||||
+ Direct access to blob, no "encoding/decoding"
|
||||
- No need to revoke anything.
|
||||
- Performance and memory losses on big blobs for encoding.
|
||||
- Performance and memory losses on big `Blob` objects for encoding.
|
||||
```
|
||||
|
||||
## Image to blob
|
||||
|
||||
We can create a blob of an image, an image part, or even make a page screenshot. That's handy to upload it somewhere.
|
||||
We can create a `Blob` of an image, an image part, or even make a page screenshot. That's handy to upload it somewhere.
|
||||
|
||||
Image operations are done via `<canvas>` element:
|
||||
|
||||
1. Draw an image (or its part) on canvas using [canvas.drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage).
|
||||
2. Call canvas method [.toBlob(callback, format, quality)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) that creates a blob and runs `callback` with it when done.
|
||||
2. Call canvas method [.toBlob(callback, format, quality)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) that creates a `Blob` and runs `callback` with it when done.
|
||||
|
||||
In the example below, an image is just copied, but we could cut from it, or transform it on canvas prior to making a blob:
|
||||
|
||||
|
@ -205,7 +205,7 @@ If we prefer `async/await` instead of callbacks:
|
|||
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
|
||||
```
|
||||
|
||||
For screenshotting a page, we can use a library such as <https://github.com/niklasvh/html2canvas>. What it does is just walks the page and draws it on `<canvas>`. Then we can get a blob of it the same way as above.
|
||||
For screenshotting a page, we can use a library such as <https://github.com/niklasvh/html2canvas>. What it does is just walks the page and draws it on `<canvas>`. Then we can get a `Blob` of it the same way as above.
|
||||
|
||||
## From Blob to ArrayBuffer
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue