URL.createObjectURL は「Blob や File に一時的な URL を貼る魔法」
URL.createObjectURL は、Blob や File に「一時的にアクセスできる URL」を発行する関数 です。
普通、<img src="..."> や <a href="..."> にはhttps://... みたいな「サーバー上の URL」を入れますよね。
でも、ブラウザの中だけで作ったデータ(Blob)や、
ユーザーが選んだローカルファイル(File)には、
そんな URL は最初から存在しません。
そこで、
「この Blob / File を指す“仮の URL”をブラウザに作ってもらう」
「その URL を img.src や a.href にセットして使う」
ということを可能にするのが URL.createObjectURL です。
この URL はブラウザの中だけで有効な「一時的な URL」で、
ページを閉じたり URL.revokeObjectURL を呼ぶと無効になります。
基本形:Blob / File → createObjectURL → href / src にセット
シグネチャと戻り値
const url = URL.createObjectURL(blobOrFile);
JavaScript引数には Blob か File を渡します。
戻り値は文字列の URL です。
例:
"blob:https://example.com/2f0c1c2b-...."
JavaScriptこの URL を、<img> の src や <a> の href にそのまま使えます。
重要ポイント:URL の中身は「ブラウザが管理している」
createObjectURL が返す URL は、
サーバーに存在するわけではありません。
ブラウザが内部的に
「この URL が来たら、この Blob / File の中身を返す」
という対応表を持っているイメージです。
だからこそ、
ネットワークに出ていかない
ローカルファイルでもプレビューできる
メモリを使うので、使い終わったら解放したほうがよい
という性質を持ちます。
例題①:File から画像プレビューを表示する
HTML
<input type="file" id="fileInput" accept="image/*">
<img id="preview" alt="プレビュー" style="max-width: 200px;">
JavaScript
const input = document.querySelector("#fileInput");
const img = document.querySelector("#preview");
input.addEventListener("change", () => {
const file = input.files[0];
if (!file) return;
const url = URL.createObjectURL(file);
img.src = url;
});
JavaScript流れを整理すると、
ユーザーが画像ファイルを選ぶ → File を受け取るURL.createObjectURL(file) で一時 URL を作る
その URL を img.src にセットする
これだけで、
ローカルの画像ファイルをアップロードせずにプレビューできます。
ここで掴んでほしいのは、
「File をそのまま img.src に渡せるわけではない」
「File → URL.createObjectURL → src という橋渡しが必要」
という感覚です。
例題②:Blob からテキストファイルをダウンロードさせる
HTML
<button id="download">テキストをダウンロード</button>
JavaScript
const btn = document.querySelector("#download");
btn.addEventListener("click", () => {
const text = "こんにちは\nこれは Blob から作ったテキストファイルです。";
const blob = new Blob([text], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "sample.txt";
a.click();
URL.revokeObjectURL(url);
});
JavaScriptここでの流れは、
文字列から Blob を作る
Blob に対して createObjectURL で一時 URL を作る<a> の href にその URL をセットし、download でファイル名を指定a.click() で擬似クリックしてダウンロード開始
最後に URL.revokeObjectURL(url) で URL を解放
というものです。
URL.createObjectURL がなければ、
「ブラウザ内のデータをファイルとしてダウンロードさせる」のはかなり面倒です。
ここでの重要ポイントは、
「Blob を“ダウンロード可能なファイル”に変える鍵が createObjectURL」
ということです。
重要ポイント:FileReader との違いをはっきりさせる
FileReader は「中身を取り出す」、createObjectURL は「URL を貼る」
よく混ざるのが FileReader との違いです。
FileReader:
ファイルや Blob の中身を
文字列(readAsText)
data URL(readAsDataURL)
ArrayBuffer(readAsArrayBuffer)
として「取り出す」ためのもの。
URL.createObjectURL:
ファイルや Blob に
「一時的にアクセスできる URL を貼る」ためのもの。
中身を自分で読むわけではない。
例えば画像プレビューなら、
どちらでも実現できます。
FileReader 版:
const reader = new FileReader();
reader.onload = () => {
img.src = reader.result; // data URL
};
reader.readAsDataURL(file);
JavaScriptcreateObjectURL 版:
const url = URL.createObjectURL(file);
img.src = url;
JavaScriptどちらも正解ですが、
FileReader は「中身を JS で扱いたいとき」
createObjectURL は「URL として扱えれば十分なとき(img.src, a.href など)」
という使い分けをするとスッキリします。
重要ポイント:URL.revokeObjectURL で「後片付け」をする
なぜ解放が必要なのか
URL.createObjectURL で作られた URL は、
ブラウザ内部に「URL → Blob / File」の対応が保持されます。
これを放置し続けると、
メモリを無駄に使い続けることになります。
そこで、
「もうこの URL は使わない」
となったタイミングで URL.revokeObjectURL(url) を呼びます。
const url = URL.createObjectURL(blob);
// 使い終わったら
URL.revokeObjectURL(url);
JavaScript小さなアプリや短時間の利用では
そこまでシビアにならなくても動きますが、
長時間動くアプリや大量の Blob を扱う場合は、
きちんと後片付けする癖をつけておくと安心です。
いつ revoke すべきかの目安
画像プレビューの場合:
画像を表示し続けるなら、その間は URL が必要
画像を差し替えるとき、古い URL を revoke する
ダウンロードの場合:
a.click() でダウンロードを開始した直後に revoke して OK
ユーザーのダウンロードは既に始まっているので問題ない
ざっくり言えば、
「その URL を参照する要素がもう存在しないタイミング」で
revoke すれば大丈夫です。
例題③:複数画像のプレビューと URL の解放
HTML
<input type="file" id="fileInput" accept="image/*" multiple>
<div id="preview"></div>
JavaScript
const input = document.querySelector("#fileInput");
const preview = document.querySelector("#preview");
// 以前の URL を覚えておく
let urls = [];
input.addEventListener("change", () => {
// 古いプレビューと URL を片付ける
preview.innerHTML = "";
urls.forEach(url => URL.revokeObjectURL(url));
urls = [];
Array.from(input.files).forEach(file => {
const url = URL.createObjectURL(file);
urls.push(url);
const img = document.createElement("img");
img.src = url;
img.style.maxWidth = "100px";
img.style.marginRight = "8px";
preview.appendChild(img);
});
});
JavaScriptここでのポイントは、
新しいファイルを選ぶたびに
古い <img> を消し、古い URL を revoke している
というところです。
これで、
「プレビューを更新するたびにメモリが増え続ける」
という状態を防げます。
初心者として URL.createObjectURL で本当に掴んでほしいこと
URL.createObjectURL は「Blob / File に一時的な URL を貼る」ための関数
その URL は img.src や a.href にそのまま使える
FileReader は「中身を取り出す」、createObjectURL は「URL として扱う」ため、と役割が違う
作った URL はブラウザが内部で Blob / File と紐づけて管理している
使い終わったら URL.revokeObjectURL(url) で解放するのが望ましい
まずは、
画像ファイルを選んで createObjectURL でプレビューする
文字列から Blob を作って createObjectURL 経由でダウンロードさせる
この 2 パターンを自分で書いてみてください。
「ローカルのファイルやメモリ上のデータが、
一瞬だけ“URL を持った存在”になる」
という感覚が一度でも掴めると、URL.createObjectURL はただの関数ではなく、
「ブラウザ内のデータと、URL ベースの世界をつなぐ小さなゲート」 に見えてきます。
