DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
CORS

How to Capture an Iframe With html2canvas (Same-Origin and Cross-Origin Cases)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

html2canvas can capture an iframe when the iframe is same-origin and has finished loading. Wait for the frame’s load event, read its contentDocument, and pass an element from that document—usually body—to html2canvas(). A cross-origin iframe cannot be read by the parent page, so useCORS or allowTaint cannot make direct capture work. Those options concern resources such as images, not the browser’s iframe security boundary.

Capture a same-origin iframe

The following example captures the complete rendered document inside #preview after the frame loads. The frame and the parent page must share an origin (scheme, host, and port), and the frame must not be sandboxed in a way that hides its origin.

<script src="https://cdn.jsdelivr.net/npm/html2canvas@latest/dist/html2canvas.min.js"></script>
<iframe id="preview" src="/preview.html" title="Preview"></iframe>
<script>
const frame = document.querySelector('#preview');

frame.addEventListener('load', async () => {
  const frameDocument = frame.contentDocument;
  if (!frameDocument) {
    throw new Error('The iframe is not same-origin or is not accessible.');
  }

  const canvas = await html2canvas(frameDocument.body, {
    backgroundColor: '#fff',
    windowWidth: frameDocument.documentElement.scrollWidth,
    windowHeight: frameDocument.documentElement.scrollHeight,
    scale: window.devicePixelRatio
  });

  document.body.appendChild(canvas);
});
</script>

html2canvas returns a Promise that resolves to a canvas. The library reconstructs the target DOM and supported styles; it does not copy the browser’s composited pixels in the way an operating-system screenshot does. Consequently, effects or embedded content that html2canvas does not implement can differ from what you see on screen. The project describes same-origin iframe support as recursive rendering and documents installation and the Promise-based API in its project documentation.

Install the library

For a bundled application, install the package with npm and import it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install html2canvas
import html2canvas from 'html2canvas';

const canvas = await html2canvas(element);

You can also use the CDN script shown above. Pin a version in production rather than relying on a moving latest URL, and test the result in the browsers you support.

Capture a specific element inside the frame

Once you have the frame document, query the component you actually need:

const frameDocument = frame.contentDocument;
const card = frameDocument.querySelector('.invoice-card');
if (!card) throw new Error('Invoice card was not found');
const canvas = await html2canvas(card, { backgroundColor: '#fff' });

The element must belong to the accessible frame document. Passing a selector found in the parent document captures the parent element instead.

Wait for the frame and its content

Register the load listener before assigning a dynamic src, or attach it immediately after markup is parsed. The event means the document load completed; images or application-rendered data may still be changing. If the frame app loads content asynchronously, wait for a frame-specific marker, a message from the app, or a short, deliberately chosen delay before calling html2canvas.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
frame.addEventListener('load', async () => {
  await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
  const ready = frame.contentDocument.querySelector('[data-render-complete]');
  if (!ready) return;
  const canvas = await html2canvas(ready);
  // use canvas here
});

Do not poll forever: add a timeout and report a useful error if the frame never reaches the expected state.

Control dimensions, cropping, and image quality

Prevent clipping

A frame’s visible viewport is often smaller than its document. Use the document’s scroll dimensions when you want a full-page render:

const doc = frame.contentDocument;
const root = doc.documentElement;
const canvas = await html2canvas(doc.body, {
  windowWidth: root.scrollWidth,
  windowHeight: root.scrollHeight,
  width: root.scrollWidth,
  height: root.scrollHeight,
  backgroundColor: '#fff'
});

windowWidth and windowHeight define the virtual window used while rendering. Explicit width and height set the canvas dimensions. Extremely large pages can exceed browser canvas limits; capture sections or reduce the scale if allocation fails.

Capture a region

Use x, y, width, and height to crop a region relative to the target:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const canvas = await html2canvas(frame.contentDocument.body, {
  x: 0,
  y: 200,
  width: 1200,
  height: 800,
  backgroundColor: '#fff'
});

Choose pixel density

scale defaults to window.devicePixelRatio. Keeping that default generally preserves sharp output on high-density displays, while scale: 1 reduces memory and file size. A larger scale increases both detail and the chance of hitting canvas-size or memory limits.

Exclude controls and overlays

Add data-html2canvas-ignore to elements that should not appear, or provide an ignoreElements predicate:

const canvas = await html2canvas(frame.contentDocument.body, {
  ignoreElements: element => element.matches('.toolbar, [data-private]')
});

This is useful for print buttons, editing handles, transient notifications, and private UI. The ignored nodes remain in the live iframe; they are omitted only from the render.

Export the canvas

PNG is the simplest lossless output. The returned data URL can be displayed, downloaded, or sent to your server:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const dataUrl = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = dataUrl;
link.download = 'iframe-capture.png';
link.click();

For JPEG, use canvas.toDataURL('image/jpeg', 0.9); transparency is not preserved in JPEG. A canvas becomes “tainted” when it contains images or other resources that violate canvas-origin rules, preventing export. Configure those resources rather than expecting iframe access settings to solve the problem.

Why cross-origin iframe capture fails

If the parent is https://app.example and the frame is https://reports.example, the parent cannot inspect frame.contentDocument under the same-origin policy. The value is inaccessible (often null), or reading it throws a security exception. This restriction exists even when both sites belong to you.

useCORS: true does not remove that restriction. It asks html2canvas to request images with CORS; the image server must return a suitable Access-Control-Allow-Origin header. allowTaint: true permits rendering potentially tainting resources, but it still does not grant access to a cross-origin iframe document and can leave the resulting canvas impossible to export. If an image host cannot provide CORS headers, use a same-origin proxy under your control or omit that image.

Rank #4
HTML5 HTML Logo Web Programmer Nerd Funny - Computer Coding T-Shirt
  • Are you familiar with html5? Then get this "HTML5 HTML Logo Web Programmer Nerd Funny" featuring HTML logo. Perfect for computer programmer, developer, software developer and technician who does computer programming language, coding and gaming on internet.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem

Sandboxed iframes

A sandboxed iframe without allow-same-origin receives a special opaque origin. Even if its URL appears to be your own site, the parent may be unable to access its DOM. Add allow-same-origin only when your security model permits it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<iframe src="/preview.html" sandbox="allow-scripts allow-same-origin"></iframe>

Sandbox permissions are security controls, not screenshot switches. Review the frame’s required capabilities before changing them; never remove sandboxing merely to make a capture work.

Options when the iframe is genuinely cross-origin

Run capture code in the framed origin

Put the html2canvas code inside the application that owns the iframe. That code can access its own DOM, create the canvas, and then send the resulting image to the parent or to a server. This requires deployment access and a deliberate data-transfer design.

Cooperate with postMessage

The parent can send a message requesting a capture; the framed app performs the capture in its own origin and returns a data URL or uploads the image. Validate event.origin on both sides, restrict accepted commands, and avoid exposing sensitive page data to untrusted parents.

// Parent
frame.contentWindow.postMessage({ type: 'capture' }, 'https://reports.example');

// Inside the framed application
window.addEventListener('message', async event => {
  if (event.origin !== 'https://app.example' || event.data?.type !== 'capture') return;
  const canvas = await html2canvas(document.body);
  event.source.postMessage(
    { type: 'capture-result', dataUrl: canvas.toDataURL('image/png') },
    event.origin
  );
});

Redesign for same-origin rendering

If you control both applications, serve the required view from the parent’s origin or proxy the data through a backend and render a same-origin representation. This changes architecture but avoids browser DOM restrictions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

Use a server-side screenshot service

A remote browser can capture pixels from a cross-origin page because it is not constrained by your parent page’s DOM access. That is a different approach from html2canvas: it captures a URL in a browser environment rather than reconstructing an iframe document in the user’s canvas.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common failures and fixes

Symptom Likely cause Fix
contentDocument is null or access throws Cross-origin URL or restrictive sandbox Capture inside the frame, use a validated postMessage protocol, or make the content same-origin; add allow-same-origin only when appropriate.
Only the visible portion appears Render dimensions equal the iframe viewport Set windowWidth/windowHeight (and, when needed, width/height) to document dimensions.
Images are missing Image requests lack CORS headers or have not loaded Wait for image readiness, set useCORS: true, and configure the image server or a same-origin proxy.
toDataURL throws a security error The canvas is tainted by a cross-origin resource Serve the resource with compatible CORS headers, proxy it, or remove it from the render.
Styles or effects differ from the screen html2canvas supports a reconstructed subset of browser rendering Simplify unsupported CSS, provide fallback styles, or use a real-browser screenshot service for pixel fidelity.
Blank or failed canvas Frame not ready, unsupported plugin content, or canvas-size limit Wait for application readiness, note that Flash/Java-style plugins are not rendered, capture smaller regions, or lower scale.

Performance and reliability checklist

  • Capture only the element or region needed instead of an entire long document.
  • Use the smallest acceptable scale; high-DPI output consumes substantially more memory.
  • Wait for a deterministic ready signal rather than an arbitrary long delay.
  • Remove animations or freeze dynamic content before capture so repeated renders are stable.
  • Handle the Promise rejection and provide a retry path for navigation, loading, and allocation failures.
  • Test fonts, images, sticky elements, and lazy-loaded content in each supported browser.
  • Remember that html2canvas is a DOM renderer, not a pixel-perfect browser screenshot.

Or skip the browser setup

For a URL-level capture—including a page that embeds a cross-origin iframe—a screenshot API can be simpler than wiring browser code. ScreenshotNeo is the first service to try here because it removes cookie banners, newsletter popups, and chat widgets before capture, bills only clean shots, and offers the lowest paid plan.

One GET request returns an image or PDF. The API reports whether a response was a clean page, a bot check, blank page, timeout, failed load, or cache hit through X-Page-Verdict and whether it was billed through X-Billed. Those unsuccessful cases are not billed. Every plan includes its MCP server, so Claude, Cursor, or another MCP client can call take_screenshot, get_page_info, and capture_pdf.

See the complete parameter reference in the ScreenshotNeo documentation. A cURL request:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; all features are included on every plan. Create a free ScreenshotNeo account to try it without adding a card.

Frequently Asked Questions

Can html2canvas capture an iframe before it loads?

No. Wait for the iframe’s load event and, for app-rendered content, an additional ready signal before calling html2canvas.

Does setting allowTaint to true fix a cross-origin iframe?

No. It affects canvas handling of tainting resources such as images; it does not permit the parent to read a cross-origin iframe document.

Can I get a PDF directly from html2canvas?

html2canvas returns a canvas. You must convert or place that image into a PDF with another library or use a browser-based PDF capture service.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Use html2canvas directly when the iframe is same-origin, accessible, and its DOM can be reconstructed. For cross-origin content, move capture into the framed origin, establish a secure messaging protocol, redesign for same-origin rendering, or capture the URL with a server-side browser service.

Quick Recap

Bestseller No. 3
Bestseller No. 4
HTML5 HTML Logo Web Programmer Nerd Funny - Computer Coding T-Shirt
HTML5 HTML Logo Web Programmer Nerd Funny - Computer Coding T-Shirt
Lightweight, Classic fit, Double-needle sleeve and bottom hem
$19.99
Bestseller No. 5
The SQL Programming Language: .
The SQL Programming Language: .
Used Book in Good Condition
$4.23

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.