Ga naar inhoud
HexaTransfer
Terug naar blog
Technische verdiepingen

Browser Opslag APIs voor Bestandsoverdracht Applications

Leverage IndexedDB, File System Access API, en Cache API voor bestand transfer apps. Opslag limits, performance, en browser compatibility.

Browseropslag voor een bestandsoverdrachtsapp verdeelt zich overzichtelijk over vier API's: IndexedDB voor gestructureerde sessie- en stukmetadata (transactioneel, asynchroon, getypeerd), de File System Access API voor het lezen en schrijven van bestanden van meerdere gigabytes rechtstreeks op de schijf van de gebruiker, de Cache API voor HTTP-antwoorden en app-shell-assets, en de Storage Manager API voor quotabeheer en persistentiehints. Origin Private File System (OPFS) staat naast deze voor gesandboxede hoge-prestatie-I/O. De AVG vereist passende technische maatregelen om persoonsgegevens te beschermen — het kiezen van de juiste opslaglaag voorkomt dat gevoelige data onbedoeld blijft hangen in een vergeetbare browseropslag die later wordt geëvicteerd. De verkeerde keuze leidt uiteindelijk tot QuotaExceededError in productie.

Elke API aan de juiste taak koppelen

Gebruik IndexedDB voor alles dat eruitziet als een rij: uploadsessies, voltooide stukindexen, sharemetadata, intrekkingstokens. Het is asynchroon, transactioneel, indexeerbaar en overleeft sessies.

Gebruik de File System Access API wanneer u bytes naar schijf moet sturen zonder het hele bestand in RAM te laden — ideaal voor het opslaan van ontsleutelde downloads boven 500 MB. Chrome, Edge en Opera ondersteunen het volledig; Firefox en Safari implementeren alleen een alleen-lezen subset via showOpenFilePicker.

Gebruik de Cache API voor HTTP Response-objecten — uw JS-bundel, CSS, pictogrammen en mogelijk gecachede API-antwoorden. Het is geoptimaliseerd voor fetch-onderschepping in Service Workers.

Gebruik OPFS (een speciale Origin-Private-tak van de File System Access API) wanneer u snelle, gesandboxede, niet-voor-gebruikers-zichtbare opslag wilt — bijvoorbeeld een schrijfbuffer tijdens een versleutelingsslag van meerdere gigabytes. Het bereikt een schijfdoorvoer een orde van grootte hoger dan IndexedDB voor binaire blobs.

IndexedDB zonder de ruwe kanten

Ruwe IndexedDB heeft een beruchte onhandige op-events-gebaseerde API. Gebruik Jake Archibald's idb-pakket (1,5 KB gegzipt) of Dexie.js (20 KB, rijkere query-API):

import { openDB } from 'idb';
const db = await openDB('transfers', 2, {
  upgrade(db, oldVersion) {
    if (oldVersion < 1) {
      const sessions = db.createObjectStore('sessions', { keyPath: 'id' });
      sessions.createIndex('by_expiry', 'expiresAt');
    }
    if (oldVersion < 2) {
      db.createObjectStore('chunks', { keyPath: ['sessionId', 'index'] });
    }
  }
});
await db.put('sessions', { id: 'abc', fileName: 'rapport.pdf', expiresAt: Date.now() + 86400000 });

Versiemigraties worden uitgevoerd in de upgrade-callback. Bewaar migraties altijd via oldVersion zodat gebruikers die van v1 naar v3 springen beide stappen doorlopen.

IndexedDB verwerkt de meeste datavormen, inclusief Blobs en File-referenties, via structured clone. Dat betekent dat u een File-handle kunt opslaan in een sessierecord en de originele bestandsbytes kunt herlezen na een tabbladherladen — ideaal voor hervattbare uploads.

File System Access API voor grote downloads

De API laat u een schrijfbare stream doorgeven aan het opslagvenster van de browser:

const handle = await window.showSaveFilePicker({
  suggestedName: 'ontsleuteld-archief.zip',
  types: [{ description: 'Zip', accept: { 'application/zip': ['.zip'] } }]
});
const writable = await handle.createWritable();
await decryptionStream.pipeTo(writable);

Bytes stromen rechtstreeks naar schijf, zonder in de JS-heap te belanden. Dit is de enige praktische manier om een ontsleuteld bestand van 10 GB in de browser op te slaan.

Voor Firefox en Safari valt u terug op StreamSaver.js, dat een Service Worker gebruikt om een streamingantwoord te synthetiseren dat de downloadinterface activeert. Dezelfde ergonomie, iets meer bewegende onderdelen.

De persistente bestandshandles laten een app ook bestanden heropenen over sessies heen. Zodra een gebruiker toestemming heeft gegeven via showOpenFilePicker, kunt u het FileSystemFileHandle opslaan in IndexedDB en later handle.requestPermission() aanroepen om toegang te herverkrijgen zonder elke keer opnieuw te vragen.

OPFS voor kladruimte

Het Origin Private File System is een per-origine gesandboxede opslag die zich gedraagt als een bestandssysteem maar niet zichtbaar is voor de gebruiker:

const root = await navigator.storage.getDirectory();
const fh = await root.getFileHandle('kladblok.bin', { create: true });
const access = await fh.createSyncAccessHandle(); // alleen in workers
access.write(buffer, { at: offset });
access.flush();
access.close();

createSyncAccessHandle is alleen beschikbaar binnen Web Workers (inclusief Service Workers). Het is synchroon en extreem snel — benchmarks tonen 3-10x IndexedDB voor opeenvolgende schrijfacties. Gebruik het om een paar honderd megabytes versleutelingsuitvoer te bufferen voor het uploaden, of om een ontsleutelde werkkopie te cachen zonder de downloadmap van de gebruiker te vervuilen.

Safari 17 leverde OPFS met synchroon-toegangshandles; Firefox 111 volgde. Alle drie grote browsers ondersteunen het nu, wat het bruikbaar maakt voor productiecode.

Opslagquota's en hoe die te overleven

Elke API deelt dezelfde origineopslagpool. Geschatte grenzen:

  • Desktop Chrome: 60% van vrije schijf
  • Desktop Firefox: 50% van vrije schijf, standaard begrensd op 2 GB per origine
  • Desktop Safari: 1 GB waarschuwing, groeit tot circa 20% van schijf met gebruikersgoedkeuring
  • iOS Safari: 1 GB per origine, agressieve evictie na 7 dagen ongebruikt
  • Chrome Android: 10% van vrije schijf, evictie onder druk

Controleer quota tijdens uitvoering:

const { quota, usage } = await navigator.storage.estimate();
console.log(`Gebruik ${(usage/1e9).toFixed(2)} GB van ${(quota/1e9).toFixed(2)} GB`);

Vraag persistentie aan voor kritieke stores:

const persisted = await navigator.storage.persist();

Retourneert true als de browser persistente opslag heeft verleend, wat betekent dat hij niet zal evicteren onder druk. Chrome verleent dit automatisch aan sites waarmee de gebruiker significant heeft geïnteracteerd; Firefox vraagt het.

Cache API voor app-shell en offline

De Cache API slaat Request + Response-paren op en is de juiste keuze in Service Workers:

const cache = await caches.open('shell-v7');
await cache.addAll([
  '/', '/app.js', '/app.css', '/pictogrammen/192.png'
]);

Ophalen bij onderschepping:

self.addEventListener('fetch', (e) => {
  e.respondWith(caches.match(e.request).then(r => r ?? fetch(e.request)));
});

Zet geen versleutelde bestandsbytes in de Cache API. Een antwoordobject van 2 GB sprengt het quota van iOS Safari in één keer en kan achteraf niet via range worden opgehaald. Bytes horen thuis in OPFS of rechtstreeks naar schijf via File System Access.

Evictie en dataverlies soepel afhandelen

Niet-persistente opslag wordt geëvicteerd — u moet ervoor plannen. iOS Safari evicteert na zeven dagen ongebruikt, ongeacht het quota. Chrome evicteert alleen wanneer de schijf werkelijk vol zit. Firefox evicteert minst-recent-gebruikte origines zodra de quotapool vol raakt.

Twee defensieve patronen:

  • Schrijf elke status die u niet kunt recreëren (uploadsessie-ID's, gedeeltelijke stukoffsets) in een herlaadbewust formaat zodat een nieuw paginaladen van de server kan ophalen en kan doorgaan.
  • Vraag voor langdurige status navigator.storage.persist() aan en toon een UI voor gebruikers om te bevestigen wanneer de browser vraagt.

Behandel de server als de waarheidsbron voor alles wat u zich niet kunt veroorloven te verliezen. Behandel browseropslag als een snelle cache die van de ene op de andere dag kan verdwijnen.

Browsercompatibiliteitsvalkuilen

Drie valkuilen duiken keer op keer op:

  1. indexedDB.databases()-opsomming wordt niet ondersteund in Firefox (gebruikers die "cookies verwijderen bij sluiten" hebben ingeschakeld, verliezen alle IndexedDB-inhoud zonder dat events worden uitgevoerd).
  2. FileSystemFileHandle.queryPermission() gedraagt zich na herladen anders — soms retourneert het 'prompt' zelfs wanneer toestemming was verleend. Roep altijd defensief requestPermission() aan.
  3. Privé/incognitomodus geeft alle drie de API's een afzonderlijk, kleiner, alleen-voor-de-sessie-geldend quota. Code die in normaal browsen werkt, kan onmiddellijk QuotaExceededError gooien in privévensters.

HexaTransfer gebruikt IndexedDB voor sessiestatus, OPFS voor ciphertekstbuffering tijdens streaming-versleuteling met AES-256-GCM, en de File System Access API voor ontsleutelde downloads van 10 GB op ondersteunde browsers. Probeer het op https://hexatransfer.com — gratis, geen account vereist, maximaal 10 GB.

Een stack kiezen voor uw app

Voor de meeste overdrachtsapps is de juiste combinatie: idb-wrapper over IndexedDB voor metadata, OPFS-synchrone toegangshandles voor versleutel/ontsleutel-kladruimte, Cache API voor app-shell in een Service Worker, File System Access API voor definitieve downloads met StreamSaver-terugval, en een navigator.storage.persist()-aanroep tijdens onboarding. Dit dekt elke vandaag uitgebrachte browser, blijft onder quota's op mobiel en herstelt soepel wanneer iets wordt geëvicteerd. Bouw kleine adapters rond elke API zodat de dag dat OPFS een nieuwe methode krijgt of Safari zijn quota verhoogt, u één bestand wijzigt en uitrolt.

Verstuur grote bestanden veilig met end-to-end-versleuteling

Draag bestanden tot 10 GB gratis over met end-to-end-versleuteling. Geen account nodig. Uw bestanden worden in uw browser versleuteld voordat ze worden geüpload — niemand anders kan ze lezen.

Een bestand verzenden