For a client-side download created with URL.createObjectURL(), intercept the Blob in the page—not the network request. Install a hook before the application runs, trigger its download action, then read the Blob in the page context and transfer its bytes to Node.js. This works because a blob: URL points to data held by the browser rather than a conventional file response.
If the page already exposes a normal <a download> link and you only need a file on disk, you can instead let Chrome save it. The right approach depends on whether you need to inspect or transform the bytes, or simply preserve the browser’s download behavior.
Why Puppeteer request interception misses a Blob download
A page can generate data locally, wrap it in a Blob, and call URL.createObjectURL(blob). The resulting blob: URL is an opaque identifier for that browser-managed object. It is not the same as a server URL returning a file, so enabling Puppeteer request interception does not give you a reliable way to capture the Blob’s bytes as a normal network response.
The useful control point is page JavaScript. You can either obtain the Blob URL and fetch it from the page that created it, or instrument URL.createObjectURL() before the application calls it. Puppeteer’s page.evaluate() executes in the page context and can await a Promise, making it suitable for reading the Blob and returning its bytes to Node.js.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors#1 Best Overall
- Model: Dell OptiPlex 7050 Small Form Factor (SFF)
- Processor: Intel Core i7-7700 3.60 GHz
- Memory: 32GB DDR4 Ram
- Storage: 1TB Solid State Drive (SSD) Fast Boot + Storage
- Operating System: Windows 11 Pro (64-bit)
Blob URLs can be revoked with URL.revokeObjectURL(). Read or retain the Blob before application code revokes the URL; revoking too early can make the URL unusable, while never releasing URLs can retain the underlying object.
Choose the interception method
| Approach | Use it when | Main trade-off |
|---|---|---|
Read the Blob through page.evaluate() |
You have a Blob URL and need the bytes for parsing, hashing, or a custom filename. | Bytes cross the page-to-Node boundary and may consume substantial memory. |
Instrument URL.createObjectURL() |
The application creates the Blob URL internally and does not expose it through an accessible selector or API. | The hook must run before URL creation; account for frames and release retained Blob references after use. |
| Let Chrome download it | The page has an anchor download flow and you need the browser to write a file without transforming it. | Chrome determines download behavior and filename; you must configure a writable destination. |
Extract Blob bytes in Node.js
This complete example records Blobs as the application creates their object URLs, triggers a configurable page control, reads the latest recorded Blob in its creating page, and writes its bytes to disk. Change targetUrl, downloadControl, and outputPath for the site you are automating. Install Puppeteer in your project before running it.
Rank #2
- AN AMAZING MAC AT A SURPRISING PRICE — With an incredibly portable and durable aluminum design, up to 16 hours of battery life,* and the A18 Pro chip, MacBook Neo is ready to go wherever school takes you.
- FOUR STUNNING COLORS. ONE DURABLE DESIGN — Choose from four beautiful colors — Silver, Blush, Citrus, or Indigo — each with a color-coordinated keyboard. And MacBook Neo is made with a durable recycled aluminum enclosure that helps it reach 60 percent recycled content by weight — the most ever in any Apple product.*
- FLY THROUGH EVERYDAY ASSIGNMENTS — Whether you’re cramming for finals, using Apple Intelligence* to summarize class notes, creating presentations, or even playing the latest Apple Arcade game,* MacBook Neo delivers the performance and AI capabilities you need to get things done.
- UP TO 16 HOURS OF BATTERY LIFE — MacBook Neo delivers all day battery life, so you can power through from early morning classes to late night study sessions without worrying about plugging in.
- A VIBRANT 13-INCH DISPLAY* — The gorgeous Liquid Retina display on MacBook Neo supports 1 billion colors, so photos and videos pop and text is crisp for easy reading.
const puppeteer = require('puppeteer');
const fs = require('node:fs/promises');
const path = require('node:path');
async function main() {
const targetUrl = 'https://example.com';
const downloadControl = 'button.export';
const outputPath = path.resolve('download.bin');
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
// Install before page code runs. Keep the original behavior intact,
// but retain Blob objects so a quick URL revocation cannot erase them.
await page.evaluateOnNewDocument(() => {
const original = URL.createObjectURL.bind(URL);
window.__blobRecords = [];
URL.createObjectURL = (value) => {
const url = original(value);
window.__blobRecords.push({
url,
blob: value instanceof Blob ? value : null,
type: value instanceof Blob ? value.type : ''
});
return url;
};
});
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
await page.click(downloadControl);
const result = await page.evaluate(async () => {
const records = window.__blobRecords || [];
const record = records[records.length - 1];
if (!record) throw new Error('No object URL was recorded');
const blob = record.blob || await (async () => {
const response = await fetch(record.url);
if (!response.ok) throw new Error(`Blob fetch failed: ${response.status}`);
return response.blob();
})();
const bytes = await blob.arrayBuffer();
return {
url: record.url,
type: blob.type || record.type,
bytes: Array.from(new Uint8Array(bytes))
};
});
await fs.mkdir(path.dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, Buffer.from(result.bytes));
console.log(`Saved ${result.bytes.length} bytes (${result.type || 'unknown type'}) to ${outputPath}`);
} finally {
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
The wrapper calls the original createObjectURL() and returns its URL unchanged. It retains a Blob reference when the argument is a Blob, so the code can read that object even if the application quickly revokes its URL. If the application creates the URL in a different frame, inspect and instrument that frame too; a main-frame hook will not capture creation performed elsewhere.
The code writes bytes, not a semantically named document. Choose an extension based on the application’s expected file format or inspect result.type; MIME type may help identify the format, but do not assume every Blob has one. For large files, avoid keeping multiple copies of the data alive longer than necessary: this example holds the serialized byte array in Node while writing it.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Rank #3
- Performance: Powered by Intel Celeron N4500 dual-core processor with up to 2.8 GHz burst frequency and 4MB L3 cache, this HP Chromebook delivers smooth multitasking for everyday computing. With 4GB LPDDR4x-2933 RAM and Intel UHD Graphics, enjoy seamless web browsing, video streaming, and productivity apps. Chrome OS boots in seconds and updates automatically, keeping your laptop secure and running at peak performance for students, professionals, and home users.
- Immersive 14-Inch HD Display: Experience clear, vibrant visuals on the 14-inch diagonal HD (1366 x 768) anti-glare display with 250 nits brightness and 62.5% sRGB color accuracy. The micro-edge design maximizes your viewing area with an impressive 80% screen-to-body ratio, perfect for streaming movies, video calls, and document editing. The anti-glare coating reduces eye strain during extended use, making it ideal for all-day productivity and entertainment in any lighting condition.
- Advanced Connectivity & Ports: Stay connected with Wi-Fi 6 (2x2) for faster wireless speeds and Bluetooth 5.3 for seamless device pairing. Equipped with versatile ports including 1 USB Type-C 10Gbps (with USB Power Delivery and DisplayPort 1.4), 2 USB Type-A 5Gbps ports, 1 HDMI 1.4b, and 1 headphone/microphone combo jack. Connect external monitors, transfer files quickly, charge your device, and expand your workspace effortlessly for maximum productivity and flexibility.
- All-Day Battery & Premium Design: The battery keeps you powered throughout your day, while the included 45W USB Type-C power adapter ensures fast charging. Featuring a sleek modern grey finish with vertical brushing pattern on the keyboard deck, this lightweight 3.35 lb Chromebook combines style and portability. The full-size modern grey keyboard and HP Imagepad provide comfortable typing and precise navigation for work, school, or entertainment on the go.
- Enhanced Security & Multimedia: Built-in H1 secure microcontroller protects your data and privacy with enterprise-grade security. The HP True Vision 720p HD camera with integrated dual array digital microphones delivers crystal-clear video calls and online meetings. HD Audio with stereo speakers provides rich, immersive sound for music, videos, and calls. With 64GB eMMC storage, you have ample space for essential files while Chrome OS seamlessly integrates with Google Drive for cloud storage.
Capture only the Blob URL when that is enough
If the application does not revoke the URL immediately and you do not need to preserve a Blob reference, a smaller hook can record just the URL. Install it before navigation or before the application bundle executes:
await page.evaluateOnNewDocument(() => {
const original = URL.createObjectURL.bind(URL);
window.__blobUrls = [];
URL.createObjectURL = (value) => {
const url = original(value);
window.__blobUrls.push(url);
return url;
};
});
After navigating and performing the UI action, get the recorded URLs with await page.evaluate(() => window.__blobUrls || []). Pass the selected URL to page.evaluate() and use fetch(blobUrl), response.blob(), and blob.arrayBuffer() to read it. Fetch it in the page context that created it: moving a Blob URL into an unrelated page or browser context can fail because its access is tied to the creating context.
Rank #4
- [INTEL POWERED CONTENT] - Built with a 8th Generation Hexa-Core Intel i5 and 32GB of DDR4 RAM; Modern, Windows 11 ready, with 4K support, Executive multitasking, media streaming and smooth, multi-tab web browsing; Perfect as an all-purpose multimedia computer; built for content creators; Plenty of RAM and Mass storage for photo and video editing powered by Intel HD 630
- [LATEST WIRELESS TECH] - This Dell Desktop Computer easily connects to the internet through the Built In WiFi / Bluetooth
- [SOLID STATE STORAGE] - This Dell Computer setup comes with an ultra-fast 1TB Solid State Drive (SSD); Setup as the primary boot device; Boot and load programs with lightning speed ; Additional expansion available
- [BUY & OWN WITH CONFIDENCE] - From the world's largest Microsoft Authorized Refurbisher; Quality Guarantee and Free Tech Support; Award-winning Customer Service; | Support Sustainable Business
- [MODERN HI-SPEED PORTS] - USB 3.0 (x4) | USB 2.0 (x4) | DisplayPort (x1) | HDMI Port (x1) | Audio Combo Jack (x1) | Audio Out (x1) | RJ-45 Ethernet (x1) | Internal SATA (x3)
A recorded URL is only useful while it remains valid. If the application revokes it before your follow-up evaluation, capture and retain the Blob itself in the hook, as in the full example, or arrange to read it before revocation.
Let Chrome save an anchor download
When the page already has a conventional <a download> flow and you do not need to inspect the bytes, configuring Chrome’s download policy is simpler. The following launch configuration allows downloads to an absolute directory:
Best Value
- 🖥POWERFUL PROCESSOR and SUPERIOR STORAGE: Configured with top of the Intel Core i5 processor for lightning-fast, reliable and consistent performance to ensure an exceptional PC experience. 16GB RAM memory to smoothly run multiple applications and browser tabs all at once. 2TB HDD storage space to store apps, games, photos, music, and movies. Loaded with 16GB to zip through multiple tasks in a hurry without lag.
- 🖥️New 22 Inch Full HD (1920x1080) LED monitor: with 75hz, High-Quality panel with quick refresh rate and response time. With 1080p resolution, you can enjoy gaming or a modern computing experience. 22 Inch monitor has a Smart Contrast to provide optimized image quality. Bezel-less and sleek design with glossy finish, crisp edge-to-edge visuals. Wide Viewing Angles for clarity from any viewpoint. VESA Mountable and built-in tilt options allow for a variety of monitor configurations.
- ⌨️ +🖱️ RGB KEYBOARD AND MOUSE | RGB SPEAKER: 3 LED Colors - Blue, red, green, Backlight LED Lights for use at night time, looks amazing. The keyboard mouse and speaker are responsive, reliable, and probably plastered in RGB lights. It's important you pick the right one for your desktop.
- 💿 WINDOWS 10 Pro LATEST: A new installation of the latest Microsoft Windows 11 Professional 64 Bit Operating System software, free of bloatware commonly installed from other manufacturers. As Microsoft's latest and best OS to date, Windows 10 Pro 64 Bit will maximize the utility of each PC for years to come. Optional software such as Anti-Virus and Office 365 can also be easily downloaded through the Microsoft Windows App Store.
const path = require('node:path');
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
downloadBehavior: {
policy: 'allow',
downloadPath: path.resolve('downloads')
}
});
const page = await browser.newPage();
await page.goto('https://example.com');
await page.click('a[download]');
For lower-level control, attach a Chrome DevTools Protocol session to the page and call Browser.setDownloadBehavior with behavior: 'allow' or behavior: 'allowAndName' and an absolute downloadPath. The page session is created with await page.createCDPSession(). If your installed Puppeteer version does not accept the launch option, use the CDP method supported by that version rather than assuming the launch configuration is available.
Starting a click is not the same as verifying a completed file. Make your automation check that the expected output exists and is complete before consuming it; for variable download times, use a bounded wait and report a timeout instead of reading a partial file. Set the policy and writable directory before clicking so Chrome does not deny the download.
The HTML download attribute supports blob: and data: URLs, but filename selection can also be affected by Content-Disposition, URL path, and Blob.type. If a particular filename matters, inspect the link’s download value and verify the saved result in your workflow.
Common failures and how to fix them
- No URL was captured: Install the hook before navigation or before the application code runs, then trigger the action that actually generates the file. Check relevant frames if the download control runs inside an iframe.
- The URL is present but fetching fails: Fetch it in the page context that created it and check whether the application revoked it. Retaining the Blob in the hook avoids relying on the URL remaining live.
- The output is empty or truncated: Await
response.blob()andblob.arrayBuffer()before writing, and do not revoke the URL before extraction. In the browser-managed path, wait for the file to finish before opening it. - Chrome denies the download: Set the browser or context download policy before clicking, and make sure the destination is an absolute writable path.
- The filename is unexpected: Check the anchor’s
downloadattribute, the Blob MIME type, and any server-providedContent-Dispositionvalue. Browser naming rules can make the saved name differ from the one you expected. - Memory use grows: Do not keep a long-lived array of large Blobs or byte arrays. Release your instrumentation records after extracting what you need, and let the page release object URLs when their lifecycle permits.
Or skip the browser setup
ScreenshotNeo is a website screenshot API, not a Blob-download interceptor: it will not extract a page’s client-side file. It is relevant if what you actually need is a screenshot or PDF of a page, rather than the downloaded bytes. A single request looks like this; see the ScreenshotNeo API documentation for its request options.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots; and the free plan includes 1,000 screenshots a month with no card, with paid plans starting at $5 for 3,000. Learn about ScreenshotNeo, or sign up free for 1,000 screenshots a month with no card.
Which method should you use?
Use page-side extraction when you need deterministic bytes, custom naming, parsing, or hashing. Instrument createObjectURL() when the application hides the Blob URL, and retain the Blob if revocation may happen quickly. Use Chrome’s download policy when a regular anchor download is sufficient and browser-managed filenames are acceptable. These approaches address different parts of the workflow: request interception is not the right mechanism for data created locally in a page.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

