The right method depends on whether the iframe is same-origin, whether you control the framed page, and whether you need a reconstructed rendering or the browser’s actual visible pixels. For a same-origin iframe, use a DOM-rendering library such as html2canvas on the frame’s document or a specific element. For a cross-origin frame, page JavaScript cannot read its DOM: arrange for the frame to capture itself and communicate with postMessage, ask the user to share a visible surface, or use a browser extension with the relevant permission.
Choose the capture method by origin and access
An origin is the combination of scheme, host, and port. For example, pages at https://example.com and https://example.com:8443 are different origins, as are HTTP and HTTPS pages on the same host. A parent page can directly inspect an iframe only when the browser’s same-origin rules permit it.
| Situation | Practical approach | What it captures |
|---|---|---|
| The iframe is same-origin | Call html2canvas on the iframe’s document body or a narrower element. | A canvas reconstructed from supported DOM and CSS, not the browser’s final pixel buffer. |
| The iframe is cross-origin and you control both pages | Capture inside the iframe, then pass the image data or a Blob to the parent using a validated postMessage exchange. |
The frame’s own DOM rendering, subject to the capture library’s support. |
| The iframe is cross-origin and you do not control it | Use a user-approved display capture flow or a browser extension with suitable permissions. | Visible browser pixels, subject to user permission and browser rules. |
Do not treat CORS as a way to read an arbitrary cross-origin iframe. CORS can affect whether particular resources, such as images, may be loaded for canvas rendering; it does not grant access to the iframe document. The browser’s same-origin policy is the security boundary (MDN: Same-origin policy).
Capture a same-origin iframe with html2canvas
html2canvas builds a representation from DOM properties rather than taking a screenshot of the browser’s rendered page. Its documentation says same-origin iframe contents are supported recursively, while cross-origin iframe contents cannot be rendered because the browser does not expose their contentDocument (html2canvas documentation).
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
Install and capture the frame
Install html2canvas in your application using your package manager, then import it into the page that contains the iframe. The following example waits for the frame load event, captures its body, and downloads a PNG:
import html2canvas from 'html2canvas';
const frame = document.querySelector('#report-frame');
if (!frame) {
throw new Error('Iframe #report-frame was not found');
}
function waitForLoad(iframe) {
if (iframe.contentDocument?.readyState === 'complete') {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
iframe.addEventListener('load', resolve, { once: true });
iframe.addEventListener('error', () => reject(new Error('Iframe failed to load')), { once: true });
});
}
await waitForLoad(frame);
const frameDocument = frame.contentDocument;
if (!frameDocument?.body) {
throw new Error('Iframe document is not accessible or has no body');
}
const canvas = await html2canvas(frameDocument.body, {
scale: window.devicePixelRatio
});
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
if (!blob) throw new Error('Could not create PNG');
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'iframe.png';
link.click();
URL.revokeObjectURL(link.href);
The selector #report-frame must match the iframe element in the parent page. If the document’s body includes unwanted margins, menus, or controls, target a specific content element instead, such as frameDocument.querySelector('.report-content'), and check that it exists before calling html2canvas.
Capture a region or adjust output quality
html2canvas accepts a target element and options for controlling the capture. Use x, y, width, and height when you need only a region of the rendered target. The scale option determines output pixel density; using window.devicePixelRatio can produce sharper output on high-density displays, at the cost of a larger canvas and more memory. Export with canvas.toBlob() for a downloadable file or canvas.toDataURL('image/png') when a data URL is specifically useful.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Wait for content, not just the iframe load event
The iframe’s load event means its document has loaded, but a single-page app may still be rendering data or images. If the target content is populated asynchronously, wait for an application-specific signal or for the target element to appear before capture. Select the content element rather than relying on a delay when possible; fixed delays are less reliable because load time varies.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Handle cross-origin frames you control
If you own both applications, put the rendering code in the iframe application. There, the frame can access its own DOM. The parent can request a capture and receive a response over window.postMessage; that API enables communication between windows that do not share an origin, but it does not bypass the same-origin policy (MDN: Window.postMessage()).
Use exact origins and validate the sender
Use the expected parent origin as targetOrigin, not *, and check both event.origin and, where appropriate, event.source before acting on a message. Send only the data the parent needs. A simplified arrangement looks like this; replace the example origins with the actual origins for your applications:
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
// In the iframe application, after its own content is ready:
const trustedParentOrigin = 'https://parent.example';
window.addEventListener('message', async event => {
if (event.origin !== trustedParentOrigin) return;
if (event.source !== window.parent) return;
if (event.data?.type !== 'CAPTURE_FRAME') return;
const element = document.querySelector('#capture-area');
if (!element) return;
const canvas = await html2canvas(element);
const image = canvas.toDataURL('image/png');
window.parent.postMessage(
{ type: 'FRAME_CAPTURE_RESULT', image },
trustedParentOrigin
);
});
// In the parent application:
const trustedFrameOrigin = 'https://frame.example';
const frame = document.querySelector('#report-frame');
window.addEventListener('message', event => {
if (event.origin !== trustedFrameOrigin) return;
if (event.source !== frame?.contentWindow) return;
if (event.data?.type !== 'FRAME_CAPTURE_RESULT') return;
// Handle event.data.image as application data; validate size and format as needed.
});
frame.contentWindow.postMessage(
{ type: 'CAPTURE_FRAME' },
trustedFrameOrigin
);
This example illustrates the security checks and message flow; production code should also handle capture failures, message timeouts, and large image payloads. For larger captures, consider transferring a Blob or another suitable representation rather than expanding the image into a large string. The iframe must be willing to perform the capture and must trust the requesting parent.
Capture a cross-origin frame you do not control
Ordinary page JavaScript cannot inspect a cross-origin iframe’s document or pass it to html2canvas. Adding CORS headers to the parent or routing images through a proxy does not remove that restriction. If you cannot change the framed application, use an approach based on permission to capture visible output instead of trying to read the frame’s DOM.
Recommended Free Tools
Ask the user to share a visible surface
navigator.mediaDevices.getDisplayMedia() opens a browser chooser for a visible tab, window, or screen. The user selects the surface and grants permission; this is not a silent capture API. The selected stream can be drawn to a canvas to obtain an image. If capture is initiated from an embedded document, browser policy and the iframe’s allow attribute can affect availability. This route is appropriate when the user is present and selecting the surface is acceptable.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Use an extension when capture is part of an extension workflow
The WebExtension tabs.captureVisibleTab() API returns a data URL for an image of the active tab’s visible area (MDN: tabs.captureVisibleTab()). A displayed cross-origin iframe is part of the visible tab image. This is an extension API, not a capability available to ordinary page scripts; the extension must comply with browser permission and UI rules. It captures the visible tab area rather than granting access to the frame’s underlying DOM.
Know what can be missing or different
DOM reconstruction is convenient for same-origin application content, but it is not identical to a screenshot taken from the browser compositor. html2canvas supports many common DOM and CSS properties, yet unsupported styling or embedded content can differ or be omitted. Video, plugin content, WebGL canvases, fonts, and cross-origin images are notable cases to check against your page. The project documents that cross-origin images can taint a canvas; useCORS can help only when the image server sends suitable headers, and a proxy may be used to fetch resources through the same origin.
- Need the actual visible pixels: favor a user-authorized display capture or extension workflow.
- Need reproducible in-page output: use same-origin DOM capture and test the CSS and embedded assets that matter.
- Need to capture content controlled by another origin: obtain cooperation from that application or use a permission-based visible capture route.
Troubleshooting common iframe capture failures
| Symptom | Likely cause | What to do |
|---|---|---|
Reading contentDocument throws or returns no usable document |
The frame is cross-origin, or a sandbox removes same-origin privileges. | Check scheme, host, and port. For sandboxed content, review whether it has allow-same-origin; do not weaken sandboxing without evaluating the security impact. If it is cross-origin, use a cooperative frame or a permission-based capture. |
| The canvas is blank or only part of the content appears | The target was captured before the app finished rendering, the selected element was wrong, or some content is unsupported. | Wait for the relevant content to be ready, verify the selector inside the frame, and test the specific CSS or embedded asset. Try a narrower target to isolate the problem. |
toDataURL() fails or the canvas cannot be exported |
A cross-origin image may have tainted the canvas. | Serve the image with suitable CORS headers and configure useCORS as appropriate, or use a same-origin proxy for the resource. These remedies concern the image resource, not iframe DOM access. |
| Capture looks soft or output is unexpectedly large | The canvas scale is too low for the desired sharpness or too high for available memory. | Choose a suitable scale, balancing detail against pixel dimensions and memory; capture only the needed element or region. |
| Cross-origin capture works only after a user action | Display capture requires user permission and a selected surface. | Keep the chooser interaction in the workflow and handle denial or cancellation as normal outcomes. If this is an extension, check its permissions and browser-specific rules. |
| The frame’s capture request is ignored | Origin/source validation, expected message type, or target origin does not match. | Log the expected origins during development, verify the event source is the intended frame, and keep exact production target origins rather than using *. |
Or skip the browser setup
If your goal is a screenshot of a public webpage rather than a capture from inside your own page, ScreenshotNeo offers a one-request screenshot API. It cannot read a private cross-origin iframe’s DOM on behalf of your page; use the cooperative or permission-based approaches above when that is required. For a page URL screenshot, one GET request returns an image or PDF:
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response reports page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Does adding CORS headers to my parent page let it read a cross-origin iframe?
No. CORS can govern access to particular cross-origin resources, but it does not grant the parent access to the iframe document.
Can html2canvas capture a cross-origin iframe if I set useCORS to true?
No. The option may help with images served using suitable CORS headers; it does not bypass the browser’s cross-origin iframe restrictions.
What is the difference between html2canvas and a screen capture?
html2canvas reconstructs an image from DOM and CSS it can access. Display capture and extension capture obtain visible browser output instead.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsQuick 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.




