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 →To capture an Amazon S3 image with html2canvas, the image response must allow your page’s origin through CORS, and html2canvas must request the image with useCORS: true. One setting alone is not enough: html2canvas cannot override the browser’s canvas security rules. If you cannot change the image server’s CORS configuration, use a carefully restricted same-origin proxy or omit the image from the capture.
Why an S3 image taints the canvas
A browser treats each scheme, host, and port combination as an origin. When a page draws an image from a different origin onto a canvas without CORS approval, the browser marks the canvas as tainted. Scripts then cannot safely read its pixels or export it with methods such as canvas.toDataURL(). MDN explains that drawing cross-origin data without CORS approval taints a canvas: MDN: CORS-enabled images.
This is why an S3 object can load visibly in a page yet be absent from a html2canvas result or cause a security error when the resulting canvas is exported. Public readability of an object and browser permission to expose its pixels to scripts are separate matters. S3 must return an appropriate Access-Control-Allow-Origin response header for the requesting page origin.
html2canvas recreates a page from browser-accessible content; it is not a browser-security bypass. Its FAQ says that cross-origin images require either useCORS: true with an appropriate server header or a proxy: html2canvas FAQ.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
Fix the bucket you control: configure S3 CORS and html2canvas
1. Add a rule for the page’s exact origin
In the Amazon S3 console, open the bucket, go to Permissions, find Cross-origin resource sharing (CORS), and edit the CORS configuration. The console expects JSON. This narrow example permits GET and HEAD requests from one site:
[
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"]
}
]
Replace https://app.example.com with the precise origin of the page running the capture: scheme, host, and port all matter. For example, an HTTP development page, a production HTTPS page, and a page on a non-default port are different origins. Add each origin that genuinely needs access as a separate entry, and keep the list as narrow as practical.
S3 matches CORS rules against the request origin, method, and requested headers; AWS states that it uses the first matching rule. The origin must match AllowedOrigins, the method must be allowed, and requested preflight headers must be allowed. See AWS S3 CORS configuration and AWS CORSRule API reference.
2. Ask html2canvas to use CORS
Use useCORS: true and leave allowTaint false when you need an exportable canvas. The image can also be marked with crossorigin="anonymous" if you load it directly using an HTML image element. The S3 response still must authorize the origin.
<div id="capture">
<img id="hero"
crossorigin="anonymous"
src="https://bucket.s3.amazonaws.com/path/image.jpg"
alt="Product illustration">
</div>
<button id="capture-button" type="button">Capture</button>
<script type="module">
import html2canvas from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";
document.querySelector("#capture-button").addEventListener("click", async () => {
const target = document.querySelector("#capture");
try {
const canvas = await html2canvas(target, {
useCORS: true,
allowTaint: false
});
document.body.appendChild(canvas);
const png = canvas.toDataURL("image/png");
console.log("Capture is exportable", png.slice(0, 40));
} catch (error) {
console.error("Capture failed", error);
}
});
</script>
The import pins the example to html2canvas 1.4.1; if your application uses a different version or bundler, keep its existing import mechanism and verify the configuration against that version’s documentation. Configuration options, including useCORS, proxy, allowTaint, and ignore-element controls, are documented at html2canvas configuration.
What the options do—and do not do
useCORS: truetells html2canvas to attempt loading an image with CORS. It cannot add permission to an S3 response that lacks the required header.allowTaintdefaults tofalse. Setting it totruemay let a tainted image be drawn, but does not make the canvas readable or exportable; it is not a fix when you need a PNG, JPEG, or pixel data.crossorigin="anonymous"sets the mode for a direct HTML image load. It does not configure the bucket and does not itself authorize the page.imageTimeoutdefaults to 15,000 milliseconds in the documented configuration. Increasing a timeout can help with slow resources but cannot correct a CORS mismatch.
Verify the response rather than guessing
- Open browser developer tools and inspect the Network entry for the exact S3 image used in the capture. Check the final request after any redirect, not just the URL in your markup.
- Confirm the request’s
Originheader is the page’s actual origin, such ashttps://app.example.com. - Inspect the response headers.
Access-Control-Allow-Originmust authorize that origin. For a non-credentialed design, a deliberately broad wildcard may be appropriate, but a specific origin is preferable when only one site needs access. - If the browser sends an
OPTIONSpreflight, check that the matching S3 rule allows the requested method and all requested headers. Rule ordering matters because S3 uses the first match. - Run the capture with
useCORS: true. Check that the image appears, then test an export such ascanvas.toDataURL("image/png")or a pixel read. A successful visual render alone does not prove that the canvas is readable. - If the test still fails, temporarily exclude the S3 image and capture again. This helps isolate another cross-origin image, font, SVG, iframe, or canvas that was already tainted.
When you cannot change the S3 bucket
Use a same-origin proxy when the image server cannot return the needed CORS header. html2canvas’s proxy option is intended to load cross-origin resources through a proxy that returns them in a browser-usable way:
const canvas = await html2canvas(document.querySelector("#capture"), {
proxy: "/image-proxy",
allowTaint: false
});
The endpoint must actually fetch the permitted image and return its bytes with an appropriate content type; merely redirecting the browser to the same S3 URL does not solve the CORS problem. Design the proxy as a security boundary, not as a generic URL-fetching service.
- Allow only expected image hosts, bucket paths, or object identifiers. Avoid accepting arbitrary URLs.
- Enforce authentication or authorization if images are private.
- Validate the response type and size, and handle redirects carefully so the proxy cannot be abused to reach internal services.
- Set suitable caching and timeouts for your application. The proxy adds server work, latency, and an endpoint that needs maintenance.
html2canvas documents the proxy option for cross-origin content when direct CORS access is unavailable: html2canvas proxy documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choose the right fallback
| Approach | Use it when | Requirement | Trade-off |
|---|---|---|---|
S3 CORS plus useCORS |
You control the bucket and the image response | A matching CORS rule and useCORS: true |
Origin, method, and requested headers must match |
| Same-origin proxy | You cannot change the image server | A controlled proxy that fetches and returns the image | Additional latency, server cost, and security surface |
| Exclude the image | The image is optional in the capture | Use data-html2canvas-ignore or an ignore predicate |
The screenshot omits that visual content |
For an optional element, html2canvas supports an ignore marker:
<img data-html2canvas-ignore
src="https://bucket.s3.amazonaws.com/path/optional.jpg"
alt="Optional decoration">
Other browser limits that CORS settings cannot remove
Cross-origin iframes
A page cannot use html2canvas options to inspect content inside a cross-origin iframe when browser same-origin protections deny access. Capturing the outer page does not grant access to the iframe’s document. The iframe’s own application would need to provide a permitted integration or image output.
Already-tainted canvases
If a canvas elsewhere in the page has already drawn unauthorized cross-origin data, drawing that canvas into another canvas can carry the taint forward. Fixing the S3 rule for a different image does not cleanse it. Identify and correct the original resource or exclude that canvas.
Other resources in the capture
Images are not the only possible cause. Fonts, SVG references, CSS background images, and other embedded content may be fetched from a different origin and behave differently from the S3 object you inspected. Check each failing request and its final response headers.
Rank #4
Troubleshooting common failures
The image displays in the page but disappears from the screenshot
Visual display only confirms that the browser could show the image; it does not establish canvas permission. Inspect the response for Access-Control-Allow-Origin, confirm it matches the page origin, then capture with useCORS: true.
useCORS: true is set, but the browser still reports CORS
Check for a scheme, host, or port mismatch, and verify that the response comes from the S3 URL or CDN actually serving the final image. Add the exact site origin to the applicable bucket rule. If the browser makes a preflight request, verify allowed methods and headers.
The S3 object URL works when opened directly
Opening a URL in a tab is not a test of whether another origin may read it through canvas. Repeat the check from the application page and inspect the cross-origin request and its response headers.
The bucket rule appears correct, but the error persists
S3 evaluates the first matching rule, so an earlier rule can affect which configuration applies. Recheck the exact origin and method in the Network panel, then inspect the final response in case a CDN, redirect, or signed URL points to a different response path.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutetoDataURL() throws a security exception
The canvas contains at least one resource that failed CORS approval or was already tainted. Keep allowTaint: false, remove or isolate resources one at a time, and verify that every image and embedded canvas in the capture is safe to read.
The image times out or fails to load
First verify the image URL, access permissions, and network response. The documented html2canvas imageTimeout default is 15,000 milliseconds; a longer value may help only when a valid image is slow. It will not fix a blocked request, missing CORS header, or inaccessible object.
Or skip the browser setup
If your goal is to capture a URL rather than export a canvas from your own page, ScreenshotNeo is a website screenshot API and MCP server that returns an image or PDF from one request. It is a different workflow from html2canvas: it captures the supplied page URL rather than granting your application JavaScript access to a tainted canvas. See the ScreenshotNeo API documentation.
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 capture; those cleanup steps can each be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up free for 1,000 screenshots a month—no card required.
Frequently asked questions
Does making an S3 object public fix CORS?
No. Public access controls whether the object can be fetched; CORS controls whether a browser page from another origin can expose the fetched response to scripts such as canvas code.
Can html2canvas capture an image inside a cross-origin iframe?
Not by changing its options. Browser same-origin restrictions still apply to iframe contents.
Is the S3 bucket itself always the server that needs configuration?
Not necessarily. If a redirect or CDN serves the final image response, inspect that response and ensure the actual serving path returns the appropriate CORS header.
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.




