Presigned URLs cover

Presigned URLs for Fast and Safe R2 Downloads

Last updated:

MV3 service workers can trigger downloads via chrome.downloads.download. For Cloudflare R2, the most robust approach is to generate a presigned GET URL and hand it to the browser. This avoids complex header signing and filename encoding pitfalls.

Generate a presigned URL

// utils/s3-fixed.js (excerpt)
export async function s3PresignGetObjectUrl({ accountId, bucket, key, accessKeyId, secretAccessKey, expires = 300 }) {
  // Build canonical query with X-Amz-* params and computed signature
  // Return URL like: https://{account}.r2.cloudflarestorage.com/{bucket}/{key}?X-Amz-Algorithm=...&X-Amz-Signature=...
}
        

Start the download

// background.js (excerpt)
const url = await s3PresignGetObjectUrl({ accountId, bucket, key, accessKeyId, secretAccessKey, expires: 300 });
await chrome.downloads.download({ url, filename: key.split('/').pop(), saveAs: false });
        

Why presigned?

See also: AWS SigV4 in the Browser for R2.

Try R2 Dashboard for free

Runs entirely in your browser. No sign-up required.