ブラウザ File API 徹底解説:ローカルファイル処理のプライバシー設計

技术架构(更新: 2026年5月20日)

ブラウザでのファイル処理の進化

初期の Web アプリは <input type="file"> とサーバーへのアップロードに依存していました。HTML5 の File API により、JavaScript がローカルファイルをアップロードなしで読めるようになりました。

これにより「ブラウザ内完結ツール」が生まれました。PDF 編集、画像圧縮、動画変換がすべてユーザーの端末上で完結し、ファイルはブラウザを離れません。


コア API の階層

File(name/size/type/lastModified を持つユーザー選択ファイル)
  ↓ extends
Blob(size/type を持つバイナリ大オブジェクト)
  ↓ 読み取り
ArrayBuffer(生バイト—WASM/暗号向け)
  ↓ または
Text(UTF-8 文字列—JSON/CSV 向け)
  ↓ または
Data URL(Base64—インライン表示向け)
  ↓ 出力
Blob → Object URL → ダウンロード / プレビュー

File と Blob

// File は Blob のサブクラスで、ファイル名と更新日時を持つ
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
  const file: File = e.target.files[0];
  console.log(file.name);         // "report.pdf"
  console.log(file.size);         // 2048576 (bytes)
  console.log(file.type);         // "application/pdf"
  console.log(file.lastModified); // 1717200000000
});

読み取り方法の比較

方法 戻り値 用途 メモリ
file.text() string JSON、CSV、テキスト 一括読み込み
file.arrayBuffer() ArrayBuffer PDF、画像、WASM 入力 一括読み込み
file.stream() ReadableStream 大ファイルのストリーム処理 チャンク読み込み
FileReader.readAsDataURL() Data URL 画像プレビュー Base64 で約 33% 増

ToolsKu の方針:50MB 未満は arrayBuffer()、50MB 超は stream() でチャンク処理


Object URL:ゼロコピーのプレビューとダウンロード

// 一時 URL(メモリ参照。ディスク上のファイルではない)
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);

// プレビュー
iframe.src = url;

// ダウンロード
const a = document.createElement('a');
a.href = url;
a.download = 'merged.pdf';
a.click();

// ⚠️ 必ず revoke。さもないとメモリリーク
URL.revokeObjectURL(url);

Object URL は blob: スキームで、メモリ上の Blob を指します。revoke しない URL はメモリを占有し続けます。バッチ処理では都度解放してください。


ドラッグ&ドロップアップロード

const dropZone = document.getElementById('drop-zone');

dropZone.addEventListener('dragover', (e) => {
  e.preventDefault(); // 必須。しないとブラウザがファイルを開く
  e.dataTransfer.dropEffect = 'copy';
});

dropZone.addEventListener('drop', (e) => {
  e.preventDefault();
  const files = Array.from(e.dataTransfer.files);
  const pdfs = files.filter(f => f.type === 'application/pdf');
  processFiles(pdfs);
});

DataTransfer.filesFileList を返し、<input type="file">files と互換です。


プライバシー設計:ローカル処理が安全な理由

従来のオンラインツールのデータフロー

ユーザーファイル → HTTPS アップロード → サーバー処理 → 結果ダウンロード → サーバー削除(と称する)
                                    ↑
                              キャッシュ・ログ・バックアップの可能性

ToolsKu のデータフロー

ユーザーファイル → File API で読み取り → ブラウザメモリ/WASM 処理 → Blob ダウンロード
                ↑
          端末を離れない
観点 サーバー処理 ブラウザローカル
転送 アップロード+ダウンロード ネットワーク転送ゼロ
プライバシー サーバーに残る可能性 タブを閉じれば消える
速度 回線速度に依存 CPU に依存
サイズ上限 多くは 10–50MB 端末 RAM
オフライン 不可 可(PWA キャッシュ後)

Streams API:超大容量ファイル

500MB を超える動画を ArrayBuffer に丸ごと載せると OOM になり得ます:

async function processLargeFile(file: File) {
  const stream = file.stream();
  const reader = stream.getReader();
  const chunks: Uint8Array[] = [];

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    chunks.push(value); // 通常 64KB ずつ
  }

  const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
  const result = new Uint8Array(totalLength);
  let offset = 0;
  for (const chunk of chunks) {
    result.set(chunk, offset);
    offset += chunk.length;
  }
  return result;
}

FFmpeg.wasm は Uint8Array を仮想ファイルシステムに書き込めます。Streams と組み合わせれば、RAM が許す範囲で数 GB の動画も処理可能です。


ファイル種別の判定:MIME とマジックバイト

File.type は OS の拡張子マッピング由来で、信頼できません

// ❌ .exe を .pdf にリネームできる
file.type === 'application/pdf' // true でも実 PDF とは限らない

// ✅ 先頭のマジックバイトを読む
const header = new Uint8Array(await file.slice(0, 5).arrayBuffer());
const isPdf = header[0] === 0x25 && header[1] === 0x50 &&
              header[2] === 0x44 && header[3] === 0x46; // %PDF

ToolsKu の MIME スニッフィングツール はマジックバイトベースで、拡張子より正確です。


ダウンロードのベストプラクティス

ダウンロードの開始

function downloadBlob(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

一括ダウンロード:ZIP

連続で多数のダウンロードを起こすとポップアップブロックされます。ToolsKu は JSZip を使用します:

PDF→画像 → 50 枚の PNG → JSZip → images.zip をダウンロード

まとめ

File API はブラウザローカルツールの基盤です。File → Blob → ArrayBuffer の変換、Object URL のライフサイクル、Streams による大ファイル処理を理解することが、プライバシー優先 Web ツール構築の核心です。ToolsKu の 200 以上のツールはこの設計に基づき、「アップロードなし・ローカル処理・閉じれば消える」を実現しています。

ブラウザローカルツールを無料で試す →

#File API#Blob#ArrayBuffer#隐私#本地处理