A common foot-gun: the user has the upload page open in two tabs (cmd-clicked a link, or navigated and didn't close the old one). They drag the same file into both. Without coordination, the server gets two parallel uploads, two database rows, two thumbnails, two billable events. AjaxUploader's crossTab option uses BroadcastChannel to lock each in-flight file by content hash (or name+size+lastModified fallback) so only one tab actually transfers it.
Try it:
- Open this demo in two browser tabs (right-click → "Open in new tab").
- Pick the same file in tab 1 and start uploading.
- Pick the same file in tab 2 — it appears in the queue but immediately fails with
cross_tab_locked instead of starting a duplicate transfer.
- Cancel in tab 1; tab 2 will succeed on its next retry.
Configuration
AjaxUploader.create('#uploader', {
uploadUrl: '/ajaxupload.axd/upload',
crossTab: true,
crossTabChannel: 'my-app-uploads' // optional namespace
});
Lock key strategy
- Preferred: the file's content hash (when
computeHash: true). Identical bytes → identical key → only one tab proceeds even when filenames differ.
- Fallback:
name + size + lastModified. Catches the obvious case (same drag-drop in both tabs) without requiring a hash pass.
- Locks are held for the life of the upload — released on success, cancel, fatal failure, and tab unload.
Pair with content-addressable storage
If your backend already deduplicates by hash, cross-tab coordination is the client-side complement: it stops the duplicate request from ever leaving the browser, saving network + server round-trips.
AjaxUploader.create('#uploader', {
computeHash: true,
hashAlgorithm: 'sha256',
crossTab: true
});
Browser support
- BroadcastChannel: all modern browsers (Chrome 54+, Firefox 38+, Safari 15.4+, Edge 79+). Service Workers + Web Workers can post to the same channel.
- Older browsers: the option becomes a no-op — uploads work normally without coordination, no errors thrown.
- Cross-origin tabs: BroadcastChannel is same-origin only by spec, so this protects against same-origin duplicates only (which is the realistic case).
Why this is unique
Uppy, FilePond, Dropzone, and FineUploader all leave duplicate-tab handling to the application layer. AjaxUploader is the first major upload component to bake it into the core option set.