This commit is contained in:
Ilya Kantor 2019-05-07 09:08:15 +02:00
parent 40074e0186
commit b7d7007d84

View file

@ -2,14 +2,12 @@
`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 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.png)
Thanks to `type`, we can download/upload blobs, and it naturally becomes `Content-Type` in network requests.
The constructor syntax is:
```js
@ -59,7 +57,10 @@ 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.
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:
Thanks to `type`, we can allso download/upload blobs, and it 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:
```html run
<!-- download attribute forces the browser to download instead of navigating -->
@ -74,7 +75,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 "on the fly" blob creation and download code, but without 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,9 +90,9 @@ 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 generated url looks like:
That's what the value of `link.href` looks like:
```
blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273
@ -99,13 +100,15 @@ 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.
A generated url is only valid while the current document is open. And it allows to reference the blob in `<img>`, `<a>`, 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.
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. So if we create an URL, that blob will hang in memory, even if not needed any more.
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.
**`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.**
**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.
In the last example, we intend the blob to be used only once, for instant downloading, so we call `URL.revokeObjectURL(link.href)` immediately.