Download a file to disk

Fetch a remote file and save it to disk. Works for images, PDFs, binaries — any file type.

Overview

Fetch a remote file and save it to disk. Works for images, PDFs, binaries — any file type.

In code

# save using the remote filename:
curl -O https://example.com/report.pdf

# save to a specific path, following redirects:
curl -L -o ./out/report.pdf https://example.com/report.pdf
import { writeFile } from 'node:fs/promises';

const res = await fetch('https://example.com/report.pdf');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buf = Buffer.from(await res.arrayBuffer());
await writeFile('report.pdf', buf);
import requests

with requests.get('https://example.com/report.pdf', stream=True) as res:
    res.raise_for_status()
    with open('report.pdf', 'wb') as f:
        for chunk in res.iter_content(chunk_size=8192):
            f.write(chunk)

Details

In curl, `-O` (capital O) saves using the last path segment of the URL as the filename, while `-o <path>` saves to a path and name you choose. Download links often redirect, so add `-L` to follow through to the final file.

Do not buffer large files entirely in memory. Use `requests` with `stream=True` + `iter_content`, or in Node pipe the response stream to a file, writing in chunks to keep memory flat.

The server's `Content-Disposition: attachment; filename="..."` header carries a suggested filename, and `Content-Length` gives the total size for a progress bar. When saving, do not blindly trust the server-supplied name — sanitize it to prevent path traversal (`../`).

Related headers

Related status codes