Free tools Windows power users keep installed

One-click scans. No signup required.

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

To save an HTML element that uses a CSS background image, render it with html2canvas, export the resulting canvas with toBlob(), and upload that Blob in FormData to a multipart endpoint. The background image must be same-origin or served with CORS; html2canvas cannot bypass the browser’s same-origin policy.

The reliable sequence is: wait for the image and layout, call html2canvas() with useCORS: true when appropriate, convert the canvas to a PNG/JPEG/WebP Blob, POST it without manually setting Content-Type, then validate and store the bytes on the server.

What the complete flow does

Suppose your page contains a design such as:

<div id="capture" class="card">
  <h1>Event announcement</h1>
</div>

<style>
.card {
  width: 900px;
  min-height: 500px;
  background: url("https://static.example.com/event.jpg") center/cover no-repeat;
}
</style>

html2canvas reconstructs the visible DOM in a canvas; it does not take a browser screenshot and does not send anything to your server by itself. Your code must then export the canvas and upload the bytes. A CSS background-image is fetched like any other image resource, so the origin and response headers determine whether the finished canvas remains readable.

Prerequisites and a suitable capture target

  • Load html2canvas in your page, for example with your package manager or a script tag from the version you have chosen.
  • Give the target element a nonzero width and height at capture time. A hidden element, collapsed container, or element whose fonts and images have not loaded can produce an incomplete result.
  • Use a stable selector such as #capture. The element’s descendants, pseudo-elements, backgrounds, and supported CSS are what html2canvas renders.
  • Decide whether the output needs transparency. PNG preserves lossless artwork and alpha; JPEG and WebP can be smaller but are lossy and do not preserve transparency in the same way.

Browser code: render, export, and upload

This example captures the element, keeps the canvas background transparent, creates a PNG Blob, and posts it under the multipart field name image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
  • Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.
async function saveCanvasToServer() {
  const target = document.querySelector('#capture');
  if (!target) throw new Error('Capture element was not found');
  if (!target.offsetWidth || !target.offsetHeight) {
    throw new Error('Capture element has no visible dimensions');
  }

  // If the background image is cross-origin, the image response must
  // include an appropriate Access-Control-Allow-Origin header.
  const canvas = await html2canvas(target, {
    useCORS: true,
    backgroundColor: null,
    imageTimeout: 15000
  });

  const blob = await new Promise((resolve, reject) => {
    canvas.toBlob(result => {
      if (result) resolve(result);
      else reject(new Error('Canvas export failed'));
    }, 'image/png');
  });

  const form = new FormData();
  form.append('image', blob, 'canvas.png');

  const response = await fetch('/api/canvas-upload', {
    method: 'POST',
    body: form
  });

  if (!response.ok) {
    throw new Error(`Upload failed: ${response.status}`);
  }
  return response.json();
}

saveCanvasToServer()
  .then(result => console.log('Saved:', result))
  .catch(error => console.error(error));

Do not add a Content-Type header to this request. The browser creates the multipart/form-data boundary and supplies the correct header. If you set it yourself, many servers cannot parse the uploaded part.

Wait for the CSS background image when timing varies

html2canvas normally discovers resources while it renders, but an image loaded from a slow or authenticated endpoint can still be late. You can wait for a known URL before capturing:

function waitForImage(url, timeout = 15000) {
  return new Promise((resolve, reject) => {
    const image = new Image();
    const timer = setTimeout(() => {
      image.src = '';
      reject(new Error(`Timed out loading ${url}`));
    }, timeout);
    image.onload = () => { clearTimeout(timer); resolve(); };
    image.onerror = () => { clearTimeout(timer); reject(new Error(`Could not load ${url}`)); };
    image.crossOrigin = 'anonymous';
    image.src = url;
  });
}

await waitForImage('https://static.example.com/event.jpg');
await saveCanvasToServer();

Waiting alone does not grant permission. The response still needs CORS headers, and redirects must end at a host that also supplies them.

Background-image CORS: the rule that decides whether export works

An image served from the page’s origin is normally safe to read. An image from another origin must opt in with CORS, typically by returning Access-Control-Allow-Origin for your page’s origin (or an appropriate wildcard for a non-credentialed request). Set useCORS: true so html2canvas requests eligible images with CORS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
  • Easily store and access 5TB of content on the go with the Seagate portable drive, a USB external hard Drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

If the image server does not cooperate, configure a server-side proxy for html2canvas. The proxy retrieves the remote image and exposes it from an origin your page is allowed to read. A proxy must be designed carefully: restrict destinations, apply size and timeout limits, and prevent it from becoming an open proxy.

What allowTaint does—and does not do

allowTaint: true permits html2canvas to draw an otherwise cross-origin image, but it does not make the pixels readable. Once a canvas contains pixels from an origin that did not grant access, the canvas is tainted. Calls to toDataURL(), toBlob(), or getImageData() can then throw a SecurityError. Use CORS or a proxy when you need to export.

backgroundColor is not a background-image loader

The backgroundColor option controls the canvas’s fallback fill. backgroundColor: null preserves transparency; a value such as '#ffffff' supplies a solid fill. It does not download a missing CSS image and cannot repair a failed background request.

Choosing an export format

Format Use it when Trade-off
PNG Text, UI artwork, diagrams, or transparency Lossless, but often larger
JPEG Photographic backgrounds where transparency is unnecessary Smaller at lower quality, but lossy
WebP Your clients and image pipeline support it Usually efficient; support and downstream tooling must be checked

For example, a JPEG Blob can be produced with a quality value between zero and one:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
  • Easily store and access 1TB to content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop. Reformatting may be required for Mac
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.
const blob = await new Promise((resolve, reject) => {
  canvas.toBlob(result => result ? resolve(result) : reject(new Error('Export failed')),
                'image/jpeg', 0.88);
});

toDataURL() is useful for a short-lived download link, but it stores the entire image as a base64 string in memory and adds encoding overhead. toBlob() creates binary data and is the practical choice for an upload.

Implement the receiving endpoint

The endpoint should accept multipart data under image, authenticate the caller, enforce a byte limit, verify both the declared MIME type and the decoded image, generate its own filename, and store the bytes in your configured filesystem or object store. Return a small JSON object containing an identifier or URL.

Node.js and Express example

Using a multipart middleware such as Multer, the application can place the uploaded part in memory and validate it before persistence. Configure limits for your workload and use an image decoder or metadata library in production rather than trusting the filename.

import express from 'express';
import multer from 'multer';
import crypto from 'node:crypto';
import fs from 'node:fs/promises';
import path from 'node:path';

const app = express();
const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 10 * 1024 * 1024 }
});

app.post('/api/canvas-upload', upload.single('image'), async (req, res) => {
  try {
    if (!req.file) return res.status(400).json({ error: 'image is required' });
    if (!['image/png', 'image/jpeg', 'image/webp'].includes(req.file.mimetype)) {
      return res.status(415).json({ error: 'unsupported image type' });
    }

    // Decode and inspect the bytes with a trusted image library here.
    const id = crypto.randomUUID();
    const filePath = path.join('/var/app/uploads', `${id}.bin`);
    await fs.writeFile(filePath, req.file.buffer, { flag: 'wx' });
    res.status(201).json({ id });
  } catch (error) {
    res.status(500).json({ error: 'could not store image' });
  }
});

app.listen(3000);

In a real deployment, replace /var/app/uploads with your object-store client or an application-managed directory, verify decoded dimensions and file signatures, and apply authorization before returning a public URL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
  • Easily store and access 4TB of content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

PHP receiving shape

With PHP’s multipart handling, the matching field is $_FILES['image']. Check the upload error, size, and detected MIME type with server-side functions, create a random destination name, move the temporary file, and reject anything that is not a decoded image. Never use the browser-supplied filename as a path.

Server contract and security checklist

  • Use authentication and authorization so one user cannot overwrite another user’s assets.
  • Set request and file-size limits at the web server, framework, and storage layers.
  • Inspect the decoded image, dimensions, and actual format; MIME headers alone are not proof.
  • Generate unpredictable server-side names and prevent path traversal.
  • Decide whether stored files are private, signed, or publicly cacheable.
  • Return JSON with an identifier rather than echoing untrusted paths.
  • Consider rate limits and cleanup for abandoned or failed uploads.

Diagnosing missing backgrounds and failed uploads

Symptom Likely cause Fix
Background is absent Bad URL, 404, redirect, unsupported CSS, or image not finished loading Open the computed URL directly, inspect the network response, wait for loading, and verify the element is not ignored.
SecurityError during export A cross-origin resource tainted the canvas Serve it with CORS and use useCORS: true, or route it through a controlled proxy.
CORS appears enabled but export still fails The final redirect host lacks the header, or credentials and allowed origins do not match Inspect every redirect and response header; configure the final image host correctly.
Canvas is blank or tiny Target has zero dimensions, is hidden, or capture ran before layout Capture a visible element after fonts, images, and layout are ready.
toBlob() callback receives null Unsupported type, failed export, or resource/memory problem Try PNG, check browser logs and canvas dimensions, and handle the null result as an error.
Server says no file was uploaded Field-name mismatch or malformed multipart boundary Use form.append('image', ...) and do not set Content-Type manually.
Upload returns 413 Proxy or application size limit is too low Raise limits deliberately or reduce dimensions/quality; keep server-side caps.

Performance and reliability considerations

Large full-page elements consume substantial browser memory during DOM cloning, rasterization, Blob creation, and network transfer. Capture only the required element, avoid unnecessary device-pixel scaling, and choose JPEG or WebP for photographic content when transparency is not needed. A client-side timeout should show a retryable error, while the server should treat duplicate requests safely if users can click repeatedly.

Do not assume that a successful HTTP response means a usable image: validate the decoded bytes before making the asset available. If the source image requires cookies or authorization, configure both the image request and your proxy/server policy consistently; public CORS settings alone may not authorize credentialed resources.

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

Or skip the browser setup

If your goal is a clean screenshot of a URL rather than a user-edited, in-browser canvas, ScreenshotNeo provides a single HTTP request. It accepts cookie and consent banners like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before capture, and reports whether a response was a clean shot or a failed page. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed.

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

See the API parameters and response details in the ScreenshotNeo documentation. A cURL request is:

Best Value
Sale
UnionSine 500GB Ultra Slim Portable External Hard Drive HDD-USB 3.0
  • [Upgraded Version] - This external hard drive features a mirrored logo stripe combined with a striped anti-slip design, and the rounded corners of the casing make it easier to grip. The stripes also have a heat dissipation function, ensuring stable and fast data transfer.
  • 【Ultra-thin and quiet】 - The motherboard adopts JMicron 578 noise-free solution, giving you a quiet working environment. Lightweight and portable size designed to fit in your pocket for easy portability.
  • 【Ultra-Fast Data Transfers】 - Pairing this external hard drive with JMicron 578 solution USB 3.0 and USB 2.0 interfaces enables blazing-fast data transfer. It boasts theoretical read speeds of up to 125MB/s and write speeds of up to 103MB/s.
  • 【Plug and Play】 - With no software to install, just plug it in and the drive is ready to use.The hard disk chip is wrapped with an aluminum anti-interference layer to increase heat dissipation and protect data.
  • 【What You Get】 - 1 x Portable Hard Drive, 1 x USB 3.0 Cable, 1 x User Manual, Gift-type shell packaging ,Three-year manufacturer's warranty and free technical support services.
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 bytes = Buffer.from(await res.arrayBuffer());
await require('node:fs').promises.writeFile('shot.webp', bytes);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Its 63 options include full-page and CSS-selector capture, lazy-image loading, device and retina settings, dark mode, custom CSS and JavaScript, clicks, waits, request blocking, headers and cookies, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and a usage API. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

When to use each approach

  • Use html2canvas when the image must reflect a logged-in user’s current DOM, local edits, form values, or a client-only composition.
  • Use a CORS-enabled asset host or proxy when the browser must export remote backgrounds.
  • Use ScreenshotNeo when you need repeatable URL captures, server-side automation, PDF output, or an AI-agent workflow without configuring browser rendering.

Frequently Asked Questions

Can html2canvas capture a CSS background image from another domain?

Only when that image response permits cross-origin access and you call html2canvas with the appropriate CORS option, or when a controlled proxy serves the image from an allowed origin.

Should I upload a data URL or a Blob?

Use a Blob for server uploads. It avoids keeping a large base64 string in memory and maps directly to a multipart FormData part.

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

Why does setting backgroundColor not restore my missing image?

backgroundColor supplies a solid canvas fill; it does not fetch, authenticate, or embed a CSS background-image.

What should the server return after saving the file?

Return a small JSON result such as an application-generated identifier or access URL after validating and durably storing the decoded image.

Quick Recap

SaleBestseller No. 1
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$129.99
Bestseller No. 2
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$229.99
Bestseller No. 3
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$119.80
Bestseller No. 4
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$189.99

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.