Start · Sprachen · JavaScript · Referenz · StorageAccessHandle.createObjectURL()

StorageAccessHandle.createObjectURL()

Methode

Erzeugt eine <strong>nicht partitionierte</strong> Blob-URL für ein <code>Blob</code> oder eine <code>MediaSource</code>, sodass auch Kontexte außerhalb der aktuellen Speicherpartition darauf zugreifen können.

seit JavaScript Chrome/Edge 125+ (experimentell, nicht Baseline) Kategorie: webapi

Signatur

StorageAccessHandle.prototype.createObjectURL(object)

Beschreibung

createObjectURL() ist das Gegenstück zu URL.createObjectURL(), gehört aber zu einem StorageAccessHandle. Dieses Handle bekommst du von document.requestStorageAccess(), wenn du die erweiterte Storage Access API (Storage Access API Extensions) nutzt und dabei { createObjectURL: true } oder { all: true } anforderst.

Normalerweise sind Blob-URLs in eingebetteten Drittanbieter-Kontexten (z. B. einem <iframe> von widget.example auf shop.example) nach dem Storage Key partitioniert. Eine URL, die im iframe mit URL.createObjectURL() erzeugt wurde, lässt sich also nicht in einem Top-Level-Fenster oder einem anders eingebetteten Kontext derselben Origin auflösen. Über das Handle erzeugte URLs landen dagegen im nicht partitionierten Blob-URL-Speicher der Origin. Sie funktionieren deshalb auch dort, wo widget.example selbst die Hauptseite ist.

Einsatzbereiche sind z. B. eingebettete Editoren, Zahlungs- oder Login-Widgets und Medienplayer, die generierte Dateien, Vorschaubilder oder Mediendaten mit ihrem eigenen Top-Level-Auftritt oder mit einem SharedWorker bzw. BroadcastChannel austauschen, der ebenfalls nicht partitioniert ist. Wie bei jeder Objekt-URL musst du den Speicher selbst wieder freigeben, und zwar mit StorageAccessHandle.revokeObjectURL().

Parameter

Name Typ Default Beschreibung
$object Pflicht Blob | File | MediaSource Das Quellobjekt, für das die Objekt-URL erzeugt wird. File erbt von Blob und ist deshalb ebenfalls erlaubt.

Rückgabewert

Typ
string
Beschreibung
Eine blob:-URL (z. B. blob:https://widget.example/5f2c…), die im nicht partitionierten Blob-URL-Speicher der Origin registriert ist.

Beispiele

Handle anfordern und nicht partitionierte Blob-URL erzeugen

// Läuft im Drittanbieter-iframe von https://widget.example
const button = document.querySelector('#export');

button.addEventListener('click', async () => {
  try {
    // Muss durch eine Nutzeraktion ausgelöst werden
    const handle = await document.requestStorageAccess({ createObjectURL: true });

    const blob = new Blob([JSON.stringify({ theme: 'dark', lang: 'de' })], {
      type: 'application/json'
    });

    const url = handle.createObjectURL(blob);
    console.log(url);
  } catch (err) {
    console.warn('Speicherzugriff verweigert:', err.name);
  }
});
blob:https://widget.example/3b8e1c2a-9f4d-4e0b-a1c7-6d2f0e9b5a11

URL über einen nicht partitionierten BroadcastChannel teilen

// iframe (Drittanbieter-Kontext)
const shareExport = async (file) => {
  const handle = await document.requestStorageAccess({
    createObjectURL: true,
    BroadcastChannel: true
  });

  const url = handle.createObjectURL(file);
  const channel = handle.BroadcastChannel('exports');
  channel.postMessage({ url, name: file.name });
};

// Top-Level-Seite https://widget.example (anderer Tab)
const channel = new BroadcastChannel('exports');
channel.onmessage = async ({ data }) => {
  const res = await fetch(data.url); // klappt, weil die URL nicht partitioniert ist
  const text = await res.text();
  console.log(`${data.name}: ${text.length} Zeichen`);
};
bericht.txt: 1024 Zeichen

Feature-Erkennung und Freigabe mit revokeObjectURL()

const createSharedUrl = async (blob) => {
  if (!('requestStorageAccess' in document)) {
    return { url: URL.createObjectURL(blob), revoke: URL.revokeObjectURL };
  }
  const handle = await document.requestStorageAccess({ createObjectURL: true });
  if (typeof handle?.createObjectURL !== 'function') {
    // Browser kennt nur die einfache Storage Access API
    return { url: URL.createObjectURL(blob), revoke: URL.revokeObjectURL };
  }
  return {
    url: handle.createObjectURL(blob),
    revoke: (u) => handle.revokeObjectURL(u)
  };
};

const { url, revoke } = await createSharedUrl(new Blob(['Hallo']));
// ... URL verwenden ...
revoke(url); // Speicher freigeben
console.log('freigegeben');
freigegeben

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Die erweiterte Storage Access API mit StorageAccessHandle gibt es bislang nur in Chromium-Browsern (ab Chrome/Edge 125). Firefox und Safari unterstützen nur das einfache requestStorageAccess() ohne Handle. Verwende deshalb immer eine Feature-Erkennung.
  • Rufst du requestStorageAccess() ohne createObjectURL: true bzw. all: true auf, wirft der Aufruf von createObjectURL() einen SecurityError.
  • requestStorageAccess() braucht in der Regel eine Nutzeraktion (transient activation), einen sicheren Kontext (HTTPS) und darf nicht durch die Permissions-Policy storage-access blockiert sein. Sonst wird das Promise abgelehnt.
  • URLs, die über das Handle erzeugt wurden, gibst du mit handle.revokeObjectURL() frei, nicht mit URL.revokeObjectURL(), denn sie liegen in einem anderen Speicher. Vergessene URLs halten den Blob bis zum Entladen des Dokuments im Speicher.
  • Datenschutz: Nicht partitionierte URLs heben die Speichertrennung gezielt auf. Teile sie nur mit Kontexten, denen du vertraust, und lege keine sensiblen Daten länger als nötig ab.