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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Set the image’s src to a complete Base64 data URL, wait until that replacement image has loaded, and only then call html2canvas(). jQuery can perform the DOM update, but it cannot bypass the browser’s same-origin policy. If the original image is hosted elsewhere, you must first obtain its bytes through a CORS-enabled response or an authorized same-origin proxy.

This guide shows a reliable implementation for one or many images, explains CORS and canvas-taint failures, covers the html2canvas options that matter, and includes troubleshooting and an API alternative when you do not need browser-side capture.

Minimal working pattern

Assume dataUrl already contains an image data URL such as data:image/png;base64,iVBORw0KGgo.... The MIME type and the base64, marker are part of the URL; assigning only the encoded payload will not work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const $image = $('#target-image');

$image.one('load error', function () {
  html2canvas(document.querySelector('#capture'))
    .then(function (canvas) {
      document.body.appendChild(canvas);
    })
    .catch(function (error) {
      console.error('html2canvas failed:', error);
    });
});

$image.attr('src', dataUrl);

The load handler is registered before changing src, so it also works when the replacement starts loading immediately. The error branch prevents a silent hang; in production, decide whether a failed replacement should cancel the capture or allow a fallback image.

#1 Best Overall
Lexar D40E 128GB Dual USB 3.2 Gen 1 Type-C Jump Drive, Champagne Silver
  • USB-C 2-in-1 storage OTG: The Lexar JumpDrive Dual Drive D40E features USB Type-A and Type-C connectors in a slim, portable form factor for easy device compatibility
  • Transfer speeds up to 100MB/s: Based on internal testing, performance may vary depending upon the host device, interface, and usage conditions. 1MB=1,000,000 bytes
  • Plug and Play: Widely compatible with USB Type-C smartphones, tablets, laptops, Macs, and traditional Type-A devices, no software installation required. The 360° swivel design allows for easy switching between connectors without the hassle of losing a cap
  • Durable & Compact: The Lexar D40E USB memory stick features a metal enclosure, withstands temperatures from 0° to 50° C (32°F to 122°F), and is lightweight at 26g with dimensions of 70.4 x 16.9 x 11.7mm
  • Security & Warranty: Securely protects files using an advanced security software solution with 256-bit AES encryption. Backed by a Lexar 3-year limited warranty

Make the replacement URL correctly

A valid image data URL has this form:

data:[媒体-type];base64,[encoded bytes]

For example:

const dataUrl = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...';
$('#target-image').attr('src', dataUrl);

Use the actual media type (image/png, image/jpeg, image/webp, or another browser-supported type). Do not URL-encode the entire string, insert line breaks, or prepend Base64 to a URL that already contains a different scheme.

Converting a Blob or byte response

If your application has a Blob, convert it before assigning src:

function blobToDataUrl(blob) {
  return new Promise(function (resolve, reject) {
    const reader = new FileReader();
    reader.onload = function () { resolve(reader.result); };
    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}

fetch('/images/logo.png')
  .then(function (response) {
    if (!response.ok) throw new Error('Image request failed: ' + response.status);
    return response.blob();
  })
  .then(blobToDataUrl)
  .then(function (dataUrl) {
    $('#target-image').attr('src', dataUrl);
  });

This example fetches a same-origin route. A cross-origin fetch() still requires that the image server permit your origin with CORS.

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

Wait for cached images as well as new loads

Browsers may complete a replacement before a later handler runs, especially when the data URL is cached. Check complete and naturalWidth after assigning src:

function waitForImage(image) {
  return new Promise(function (resolve, reject) {
    function done() {
      image.removeEventListener('load', onload);
      image.removeEventListener('error', onerror);
    }
    function onload() { done(); resolve(image); }
    function onerror() { done(); reject(new Error('Image could not be decoded')); }

    if (image.complete) {
      if (image.naturalWidth > 0) return resolve(image);
      return reject(new Error('Image completed without usable pixels'));
    }
    image.addEventListener('load', onload, { once: true });
    image.addEventListener('error', onerror, { once: true });
  });
}

const image = document.querySelector('#target-image');
image.src = dataUrl;
waitForImage(image)
  .then(function () {
    return html2canvas(document.querySelector('#capture'));
  })
  .then(function (canvas) {
    document.body.appendChild(canvas);
  });

Set src before calling waitForImage. The function resolves only when the browser reports usable intrinsic dimensions.

Rank #2
KOOTION USB C Flash Drive 32GB 2 in 1 OTG USB 3.0/Type C Thumb Drive Dual Drive USB C Memory Stick for Smartphone Laptop Tablet PC, Blue
  • 2 in 1: USB C + USB 3.0, 32GB usb c flash drive has dual ports, usb 3.0 port is applied to all devices which have usb 3.0 interface and usb c port is widely used in all Android smartphones with OTG function
  • High Speed USB 3.0: Read speed up to 90 MB/s, Write speed up to 30 MB/s, the speed of USB 3.0 interface is faster than USB 2.0, save time to wait, increases work productivity. Note: Speed will be limited if you use the USB key in the USB 2.0 interface
  • Large Compatibility: The USB 3.0 Connector is compatible with USB 3.0 & USB 2.0 backward USB 1.1 devices, such as Laptop, Desktop, Car Audio, Tablet, TV, Speakers, Projector. USB-C port is compatible with all Android Smartphones
  • Expand Storage: Good performance in storing, transferring and sharing digital data with families, friends, colleagues, customers. It can expand the capacity of smartphone, you can watch movies or share pictures when you go on vacation with your family
  • Note: Make sure your smartphone is equipped with OTG function and need to open OTG function in Settings when you plug memory stick, then you can transfer easily data bewteen different devices

Replacing several images before capture

Capture should begin after every replacement has either loaded or failed according to your policy. This version aborts on the first failure:

async function replaceAndCapture(replacements) {
  const waits = replacements.map(function (item) {
    const image = document.querySelector(item.selector);
    if (!image) throw new Error('Missing image: ' + item.selector);
    image.src = item.dataUrl;
    return waitForImage(image);
  });

  await Promise.all(waits);
  const canvas = await html2canvas(document.querySelector('#capture'));
  document.body.appendChild(canvas);
  return canvas;
}

replaceAndCapture([
  { selector: '#avatar', dataUrl: avatarDataUrl },
  { selector: '#chart', dataUrl: chartDataUrl }
]).catch(console.error);

If a missing image is acceptable, replace Promise.all with Promise.allSettled, inspect each result, and remove or hide failed elements before capture. Do not let a rejected promise leave the UI waiting indefinitely.

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

Export the html2canvas result

The Base64 assigned to the source image and the data URL produced by the output canvas are separate values. Once the Promise resolves, call toDataURL() on the resulting canvas:

html2canvas(document.querySelector('#capture'))
  .then(function (canvas) {
    const pngDataUrl = canvas.toDataURL('image/png');
    const link = document.createElement('a');
    link.href = pngDataUrl;
    link.download = 'capture.png';
    link.click();
  });

PNG output is lossless but can be large. Use image/jpeg and a quality value such as 0.9 only when JPEG’s lossy compression and lack of transparency are acceptable. The official examples demonstrate canvas export at html2canvas examples.

Why CORS still matters

Base64 is not a permission mechanism. It solves the browser’s remote-loading problem only after your application has legitimately obtained the bytes. A remote image loaded without permission can taint the canvas, making operations such as toDataURL() fail for security reasons.

Rank #3
Lexar D40E 64GB Dual USB 3.2 Gen 1 Type-C Jump Drive, Champagne Silver
  • USB-C 2-in-1 storage OTG: The Lexar JumpDrive Dual Drive D40E features USB Type-A and Type-C connectors in a slim, portable form factor for easy device compatibility
  • Transfer speeds up to 100MB/s: Based on internal testing, performance may vary depending upon the host device, interface, and usage conditions. 1MB=1,000,000 bytes
  • Plug and Play: Widely compatible with USB Type-C smartphones, tablets, laptops, Macs, and traditional Type-A devices, no software installation required. The 360° swivel design allows for easy switching between connectors without the hassle of losing a cap
  • Durable & Compact: The Lexar D40E USB memory stick features a metal enclosure, withstands temperatures from 0° to 50° C (32°F to 122°F), and is lightweight at 26g with dimensions of 70.4 x 16.9 x 11.7mm
  • Security & Warranty: Securely protects files using an advanced security software solution with 256-bit AES encryption. Backed by a Lexar 3-year limited warranty

Same-origin image

If the image URL uses the same scheme, host, and port as the page, direct loading is simplest. A same-origin endpoint can also fetch and return the image, after validating the requested resource.

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

CORS-enabled image host

When the image server returns an appropriate Access-Control-Allow-Origin header, request it with CORS enabled:

html2canvas(document.querySelector('#capture'), {
  useCORS: true
}).then(function (canvas) {
  document.body.appendChild(canvas);
});

useCORS asks the browser to use a CORS image request; it cannot manufacture the response header. The host must explicitly allow your origin. See the html2canvas FAQ and MDN’s guide to CORS-enabled canvas images.

Same-origin proxy

If you control neither the page nor the image host, an application proxy can retrieve the image and serve it from your own origin. Restrict destinations to an allowlist, validate content types and response sizes, enforce timeouts, and avoid exposing an unrestricted URL-fetching endpoint. html2canvas documents the proxy option, but does not endorse a particular provider.

html2canvas(document.querySelector('#capture'), {
  proxy: '/image-proxy',
  imageTimeout: 15000
});

A proxy adds server work and another failure point. Use it only when the remote server cannot be configured for CORS and you are authorized to retrieve the resource.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
2-Pack 128GB USB C Flash Drive Dual Type C + USB A Memory Stick Jump Drive 2-in-1 Thumb Drive for Storage and Backup (128GB*2 Black&Blue)
  • 2-in-1 Dual Design: Features both USB-C and USB-A connectors, making it compatible with phones, tablets, MacBooks, PCs, and laptops-no adapter needed
  • Wide Compatibility: Works seamlessly with USB A and USB C devices, ensuring reliable file transfers across smartphones, computers, and more
  • Ample Storage Options: Available in 16GB/32GB/64GB/128GB providing plenty of space for photos, videos, music, and documents
  • Portable & Lightweight: Compact and durable design for travel, school, or daily use-take your files anywhere
  • Plug-and-Play Convenience: No software or drivers required; simply insert into USB-C or USB-A ports and start transferring files instantly

Important html2canvas options and limitations

html2canvas reconstructs a canvas from the DOM and styles it understands; it is not a literal screenshot of browser pixels. Unsupported CSS, browser differences, animations, video frames, fonts, and cross-origin resources can produce output different from what a user sees. The project describes these limits in its documentation.

Option Purpose and caution
useCORS Attempts CORS loading for images. Default documented value is false; the server still needs the correct header.
proxy Routes resource requests through a proxy. Default is null; operate a restricted, authorized proxy.
allowTaint Allows drawing cross-origin images that taint the canvas. It does not make a tainted canvas exportable, so it is not a fix for toDataURL errors.
imageTimeout Maximum image wait in milliseconds; the documented default is 15000. Verify values against your installed release.
onclone Callback for changing the cloned document before rendering, useful for hiding controls or replacing content only in the capture copy.

Defaults and supported options can change. Check the configuration reference for the version installed in your project.

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

Common failures and fixes

“The image does not appear”

  • Confirm that src starts with data:image/ and contains ;base64,.
  • Check the browser console and the image’s naturalWidth; malformed Base64 or an incorrect MIME type causes a decode error.
  • Wait for load before invoking html2canvas.

“Tainted canvases may not be exported”

  • Find every image, CSS background, font, or other resource used inside the capture—not only the image you replaced.
  • Move resources to the same origin, configure the host’s CORS header and use useCORS: true, or use a controlled same-origin proxy.
  • Do not rely on allowTaint: true if you need toDataURL().

The capture runs before replacement

Do not call html2canvas immediately after .attr('src', dataUrl). Use the load/error Promise pattern and handle the already-complete case with naturalWidth.

Some content is missing or visually different

Inspect html2canvas’s supported CSS behavior, disable transitions during capture, wait for web fonts and lazy content, and use onclone for capture-only changes. A DOM reconstruction cannot reproduce browser features the library does not implement.

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.

Large or slow captures

Reduce the capture area, avoid needlessly large Base64 strings, wait for only the resources required, and consider a server-side screenshot when the page is complex. Base64 increases in-memory representation size compared with binary bytes, so do not store huge images in repeated DOM updates.

Best Value
Samsung Type-C USB Flash Drive 256GB, USB 3.2 Gen 1, Up to 400MB/s
  • USB-C STORAGE ON THE GO: This sleek drive is supported by Samsung NAND flash and is incredibly compact to fit in the palm of your hand; Count on reliable performance and fast transfer speeds while staying compact
  • PERFORMANCE WITH SPEED: No need to choose between performance and reliability; Experience a fast, powerful flash drive that transfers 4GB files in just 11 seconds with up to 400MB/s USB 3.2 Gen 1 read speeds and is backward compatible with USB 3.0/2.0
  • MODERN MEETS ICONIC: The ultra-sleek USB-C drive looks as good as it performs; Featuring a reversible plug, the Type-C inserts into your devices seamlessly every time; Transfer large files with style and ease
  • ALWAYS CONNECTED: USB-C is compatible across devices, including laptops, tablets, phones and cameras, with enough space for 63,730 photos or maximum 12 hours of 4K video; With up to 256GB of storage space, this pocket-sized thumb drive comes in handy wherever you go
  • TOUGH & TRUSTED: Files stay secure, no matter the terrain; Samsung's flash memory technology makes the Type-C a trustworthy drive to store your valuable data; It's waterproof, shock-proof, magnet-proof, temperature-proof, and X-ray-proof body, plus it's backed by a 5-year limited warranty

Or skip the browser setup

If your goal is simply a clean image or PDF of a URL, ScreenshotNeo returns it from one request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

See the ScreenshotNeo API documentation for all options, including full-page and element captures, device presets, custom CSS and JavaScript, request blocking, cookies, headers, geolocation, PDF settings, caching, signed links, asynchronous jobs, bulk capture and usage reporting.

cURL

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)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

The Free plan includes 1,000 screenshots each month with no card. Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing provides two months free, and every feature is on every plan. Create a free ScreenshotNeo account.

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

Choosing the right approach

Situation Recommended path
Image already belongs to your site Assign the data URL, wait for load, then call html2canvas.
Remote host supports your origin Use CORS headers and useCORS: true.
Remote host cannot be changed Use a restricted same-origin proxy only when authorized.
You need a URL screenshot rather than DOM-side composition Use ScreenshotNeo’s API or MCP server.

Frequently Asked Questions

Can I assign a Base64 string without the data URL prefix?

No. The image source must include the media type and the ;base64, delimiter, for example data:image/png;base64,....

Does jQuery’s .attr('src', ...) disable CORS checks?

No. It only changes the DOM attribute; the browser still enforces the image server’s CORS policy.

Why does toDataURL() fail even after I replaced one image?

Another resource inside the capture—such as a CSS background or remote font—may have tainted the canvas. Audit all captured resources and make each same-origin, CORS-enabled, or proxied.

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.

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