Browser Storage APIs for फ़ाइल ट्रांसफ़र Applications
IndexedDB, File System Access API, और Cache API को फ़ाइल ट्रांसफ़र apps के लिए उपयोग करें। Storage limits, performance, और browser compatibility।
फ़ाइल ट्रांसफ़र app के लिए browser storage चार APIs में साफ-साफ विभाजित होती है: structured session और chunk metadata के लिए IndexedDB (transactional, async, typed), user की disk पर सीधे multi-gigabyte फ़ाइलें पढ़ने-लिखने के लिए File System Access API, HTTP responses और app-shell assets के लिए Cache API, और quota management और persistence hints के लिए Storage Manager API। Origin Private File System (OPFS) sandboxed high-performance I/O के लिए इनके साथ है। सही चुनना मायने रखता है क्योंकि limits iOS Safari पर 1 GB से लेकर desktop Chrome पर "60% of free disk" तक होती हैं, और गलत choice अंततः production में QuotaExceededError की ओर ले जाती है।
प्रत्येक API को सही काम से map करना
IndexedDB के लिए कुछ भी जो row जैसा दिखे: upload sessions, completed chunk indexes, share metadata, revocation tokens। यह async, transactional, indexable है, और sessions के पार survive करता है।
File System Access API तब उपयोग करें जब आपको पूरी फ़ाइल को RAM में load किए बिना bytes को disk पर देना हो — 500 MB से अधिक decrypted downloads save करने के लिए आदर्श। Chrome, Edge, और Opera इसे support करते हैं; Firefox और Safari केवल showOpenFilePicker के माध्यम से read-only subset implement करते हैं।
Cache API के लिए HTTP Response objects — आपका JS bundle, CSS, icons, और शायद cached API responses। यह Service Workers में fetch interception के लिए optimized है।
OPFS (File System Access API की एक विशेष Origin-Private शाखा) तब उपयोग करें जब आप fast, sandboxed, non-user-visible storage चाहते हों, उदाहरण के लिए multi-gigabyte encryption pass के दौरान write buffer। यह binary blobs के लिए IndexedDB से एक order of magnitude अधिक disk throughput तक पहुँचता है।
IndexedDB बिना खुरदरे किनारों के
Raw IndexedDB में एक कुख्यात awkward event-based API है। Jake Archibald का idb package (1.5 KB gzipped) या Dexie.js (20 KB, richer 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: 'report.pdf', expiresAt: Date.now() + 86400000 });
Version migrations upgrade callback में चलते हैं। हमेशा migrations को oldVersion से guard करें ताकि v1 से v3 पर जाने वाले users को दोनों steps मिलें।
IndexedDB Blobs और File references सहित अधिकांश data shapes, structured clone के माध्यम से handle करता है। इसका मतलब है कि आप एक session record में File handle store कर सकते हैं और tab reload के बाद original file bytes फिर से पढ़ सकते हैं — resumable uploads के लिए परफेक्ट।
बड़े Downloads के लिए File System Access API
API browser के save dialog को एक writable stream देने देती है:
const handle = await window.showSaveFilePicker({
suggestedName: 'decrypted-archive.zip',
types: [{ description: 'Zip', accept: { 'application/zip': ['.zip'] } }]
});
const writable = await handle.createWritable();
await decryptionStream.pipeTo(writable);
Bytes सीधे disk पर flow करते हैं, JS heap में कभी नहीं उतरते। यह browser में 10 GB decrypted फ़ाइल save करने का एकमात्र व्यावहारिक तरीका है।
Firefox और Safari के लिए, StreamSaver.js पर fall back करें, जो एक Service Worker उपयोग करता है download UI trigger करने वाली streaming response synthesize करने के लिए। समान ergonomics, थोड़े अधिक moving parts।
Persistent file handles एक app को sessions के पार फ़ाइलें फिर से खोलने देते हैं। एक बार user showOpenFilePicker के माध्यम से permission दे, आप FileSystemFileHandle को IndexedDB में persist कर सकते हैं और बाद में प्रत्येक फ़ाइल के लिए re-prompt किए बिना access फिर से हासिल करने के लिए handle.requestPermission() call कर सकते हैं।
Scratch Space के लिए OPFS
Origin Private File System एक per-origin sandboxed storage है जो filesystem जैसा व्यवहार करती है लेकिन user को दिखती नहीं:
const root = await navigator.storage.getDirectory();
const fh = await root.getFileHandle('scratch.bin', { create: true });
const access = await fh.createSyncAccessHandle(); // workers only
access.write(buffer, { at: offset });
access.flush();
access.close();
createSyncAccessHandle केवल Web Workers के अंदर उपलब्ध है (Service Workers सहित)। यह synchronous और बेहद तेज़ है — benchmarks sequential writes के लिए IndexedDB से 3-10x दिखाते हैं। Upload से पहले कुछ सौ megabytes encryption output buffer करने के लिए, या user के Downloads folder को pollute किए बिना decrypted working copy cache करने के लिए उपयोग करें।
Safari 17 sync access handles के साथ OPFS ship किया; Firefox 111 ने पीछा किया। तीनों प्रमुख browsers अब इसे support करते हैं, जो इसे production code के लिए viable बनाता है।
Storage Quotas और उन्हें Survive करना
प्रत्येक API एक ही origin quota pool share करता है। अनुमानित limits:
- Desktop Chrome: free disk का 60%
- Desktop Firefox: free disk का 50%, default पर प्रति origin 2 GB तक
- Desktop Safari: 1 GB warning, user approval के साथ ~20% disk तक बढ़ता है
- iOS Safari: प्रति origin 1 GB, अनुपयोग होने पर aggressive 7-दिन eviction
- Chrome Android: free disk का 10%, pressure में eviction
Runtime पर quota जाँचें:
const { quota, usage } = await navigator.storage.estimate();
console.log(`Using ${(usage/1e9).toFixed(2)} GB of ${(quota/1e9).toFixed(2)} GB`);
Critical stores के लिए persistence request करें:
const persisted = await navigator.storage.persist();
True return करता है यदि browser ने persistent storage दी, मतलब यह pressure में evict नहीं करेगा। Chrome इसे automatically उन sites को देता है जिनके साथ user ने काफी engage किया है; Firefox prompt करता है।
App Shell और Offline के लिए Cache API
Cache API Request + Response pairs store करता है और Service Workers के अंदर सही choice है:
const cache = await caches.open('shell-v7');
await cache.addAll([
'/', '/app.js', '/app.css', '/icons/192.png'
]);
Intercept पर retrieve करें:
self.addEventListener('fetch', (e) => {
e.respondWith(caches.match(e.request).then(r => r ?? fetch(e.request)));
});
Cache API में encrypted file bytes न डालें। एक 2 GB response object iOS Safari का quota एक बार में blow past कर देता है और बाद में range-fetch नहीं किया जा सकता। Bytes OPFS में या File System Access के माध्यम से direct-to-disk में हैं।
Eviction और Data Loss को Gracefully Handle करना
Non-persisted storage evict होती है — आपको इसके लिए plan करना होगा। iOS Safari quota की परवाह किए बिना 7 दिन non-use के बाद evict करता है। Chrome केवल तभी evict करता है जब disk वास्तव में pressured हो। Firefox quota pool भरने पर least-recently-used origins को evict करता है।
दो defensive patterns:
- कोई भी state जिसे आप recreate नहीं कर सकते (upload session IDs, partial chunk offsets) reload-friendly format में लिखें ताकि fresh page load server से re-fetch कर सके और continue कर सके।
- Long-lived state के लिए,
navigator.storage.persist()request करें और जब browser prompt करे तो users के लिए confirm करने का UI surface करें।
किसी भी ऐसी चीज़ के लिए server को truth का source मानें जिसे आप खोना afford नहीं कर सकते। Browser storage को एक fast cache मानें जो रात भर में गायब हो सकती है।
Browser Support के Landmines
तीन traps बार-बार सामने आते हैं:
indexedDB.databases()enumeration Firefox में supported नहीं है (जो users "delete cookies on close" opt-in करते हैं वे events fire किए बिना सभी IndexedDB content खो देते हैं)।FileSystemFileHandle.queryPermission()reloads के बाद अलग व्यवहार करता है — कभी-कभी'prompt'return करता है भले ही granted हो। हमेशा defensivelyrequestPermission()call करें।- Private / incognito mode सभी तीन APIs को एक अलग, छोटा, session-only quota देता है। code जो normal browsing में काम करता है private windows में तुरंत
QuotaExceededErrorhit कर सकता है।
HexaTransfer session state के लिए IndexedDB, streaming encryption के दौरान ciphertext buffering के लिए OPFS, और supported browsers पर 10 GB decrypted downloads के लिए File System Access API उपयोग करता है। hexatransfer.com पर आज़माएं — मुफ़्त, कोई अकाउंट नहीं, अधिकतम 10 GB।
अपने App के लिए Stack चुनना
अधिकांश transfer apps के लिए, सही combination है: metadata के लिए IndexedDB पर idb wrapper, encrypt/decrypt scratch space के लिए OPFS sync access handles, Service Worker के अंदर app shell के लिए Cache API, StreamSaver fallback के साथ final downloads के लिए File System Access API, और onboarding के दौरान एक navigator.storage.persist() call। यह आज shipping हर browser को cover करता है, mobile पर quotas के अंदर रहता है, और जब कुछ evict हो जाए तो gracefully recover करता है। प्रत्येक API के आसपास छोटे adapters बनाएं ताकि जिस दिन OPFS एक new method land करे या Safari अपना quota बढ़ाए, आप एक फ़ाइल बदलें और ship करें।
एंड-टू-एंड एन्क्रिप्शन के साथ बड़ी फ़ाइलें सुरक्षित रूप से भेजें
एंड-टू-एंड एन्क्रिप्शन के साथ 10 GB तक की फ़ाइलें मुफ़्त में ट्रांसफ़र करें। अकाउंट की आवश्यकता नहीं। अपलोड से पहले आपकी फ़ाइलें ब्राउज़र में एन्क्रिप्ट की जाती हैं — कोई और उन्हें पढ़ नहीं सकता।
फ़ाइल भेजें