Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
Base64

How to Convert an Image URL to Base64 in JavaScript

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

In a browser, convert an image URL to a complete Base64 data URL with fetch(), Response.blob(), and FileReader.readAsDataURL(). The result looks like data:image/jpeg;base64,... and can be assigned directly to img.src. If another API wants only the Base64 characters, remove everything through the first comma.

The standard browser conversion

This function downloads the image, verifies the HTTP response, reads the bytes as a Blob, and asks FileReader to create a data URL. It preserves the downloaded representation rather than drawing the image onto a canvas or re-encoding it.

async function imageUrlToDataUrl(url) {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Image request failed: ${response.status} ${response.statusText}`);
  }

  const blob = await response.blob();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener('load', () => resolve(reader.result), { once: true });
    reader.addEventListener('error', () => reject(reader.error), { once: true });
    reader.readAsDataURL(blob);
  });
}

const dataUrl = await imageUrlToDataUrl('https://example.com/photo.jpg');
console.log(dataUrl);

dataUrl is a string containing the media declaration, a comma, and the encoded payload. The declaration is generated from the Blob’s MIME type, so it may be image/jpeg, image/png, image/webp, or another type returned by the server. Do not force image/png unless you actually converted the image to PNG.

Use the result as an image source

const img = document.querySelector('#preview');
img.src = dataUrl;

A data URL is self-contained, so the browser does not need to make a second request for the image. It is useful for previews, inline HTML, or APIs that explicitly accept data URLs.

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

Return only raw Base64

Some APIs require the payload without data:image/...;base64,. Strip the prefix only at that boundary:

function dataUrlToBase64(dataUrl) {
  return dataUrl.slice(dataUrl.indexOf(',') + 1);
}

const base64 = dataUrlToBase64(dataUrl);
console.log(base64);

Keep the full data URL when the consumer expects an img source or another data-URL value. Removing the prefix too early loses the MIME declaration that tells a consumer what the bytes represent.

Cross-origin images and CORS

The most common failure is not JavaScript syntax; it is the browser’s same-origin policy. A script can fetch an image hosted on another origin only when that server’s response permits the requesting origin with appropriate CORS headers.

An image loading successfully in ordinary HTML does not prove that JavaScript may read its bytes. The <img> element can display many cross-origin resources, while fetch() still rejects a response that lacks CORS permission. Client-side code cannot manufacture that permission. If you control the image server, configure its CORS policy for the site that runs this code. Otherwise, use a server-side request you control or obtain an endpoint that intentionally grants access.

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.

Do not treat a public CORS proxy as a general solution. It adds a third party that can observe, alter, rate-limit, or discontinue access to the image, and it does not change the image owner’s CORS policy.

Diagnose a CORS failure

  • Open the browser developer tools and inspect the failed request in the Network panel.
  • Check whether the response contains an Access-Control-Allow-Origin value matching your page’s origin (or an appropriate permitted value).
  • Confirm that the URL is an image endpoint, not an HTML login page, redirect, or hotlink-protection response.
  • If the server cannot be changed, move the download to your own backend and return the bytes from an endpoint designed for your application.

Canvas: use it when you need a rendered or transformed image

Canvas is an alternative when the image is already displayed in the page or you need to resize, crop, draw, or otherwise transform it. It does not simply expose the original response bytes: drawing and exporting can change the representation, metadata, and format.

function imageElementToDataUrl(img, type = 'image/png', quality) {
  const canvas = document.createElement('canvas');
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;

  const context = canvas.getContext('2d');
  if (!context) throw new Error('Could not create a 2D canvas context');

  context.drawImage(img, 0, 0);
  return canvas.toDataURL(type, quality);
}

const existingImage = document.querySelector('#source');
const renderedDataUrl = imageElementToDataUrl(existingImage, 'image/jpeg', 0.85);

For a remote image, set crossOrigin before assigning src, and make sure the host grants CORS access:

const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
  document.querySelector('#preview').src = imageElementToDataUrl(img);
};
img.onerror = () => console.error('The image could not be loaded');
img.src = 'https://example.com/photo.jpg';

If foreign-origin pixels are drawn without the required permission, the canvas becomes tainted. Reading it with toDataURL() then throws a SecurityError. Setting crossOrigin is necessary but not sufficient; the remote response must also contain the matching CORS approval.

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

toDataURL() versus toBlob()

toDataURL() returns an image data URL. If the type is omitted or unsupported, the canvas export defaults to PNG. The entire encoded image is held in an in-memory string, which can be expensive for large images. For large output, MDN generally recommends toBlob() together with URL.createObjectURL() instead of building a large data URL.

function canvasToBlob(canvas, type = 'image/png', quality) {
  return new Promise((resolve, reject) => {
    canvas.toBlob(blob => {
      if (blob) resolve(blob);
      else reject(new Error('Canvas could not be encoded'));
    }, type, quality);
  });
}

const canvas = document.querySelector('#canvas');
const blob = await canvasToBlob(canvas, 'image/webp', 0.85);
const temporaryUrl = URL.createObjectURL(blob);
document.querySelector('#preview').src = temporaryUrl;
// Call URL.revokeObjectURL(temporaryUrl) when the preview is no longer needed.

Use the fetch-and-FileReader path when preserving the downloaded bytes matters. Use canvas when you intentionally want a rendered export.

Converting a file selected by the user

A local File obtained from an <input type='file'> is a Blob subtype, so the same FileReader method works without a URL request:

const input = document.querySelector('#file-input');
input.addEventListener('change', () => {
  const file = input.files[0];
  if (!file) return;

  const reader = new FileReader();
  reader.addEventListener('load', () => {
    const dataUrl = reader.result;
    document.querySelector('#preview').src = dataUrl;
  }, { once: true });
  reader.addEventListener('error', () => {
    console.error(reader.error);
  }, { once: true });
  reader.readAsDataURL(file);
});

This produces the same kind of complete data URL. If an upload service asks for raw Base64, pass the result through dataUrlToBase64() after the read completes.

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

Which method should you choose?

Need Use Important consideration
Preserve bytes fetched from an image URL fetch() → blob() → readAsDataURL() Cross-origin requests require server CORS permission; output is a complete data URL.
Convert a local file input FileReader.readAsDataURL(file) A selected File is already a Blob; remove the declaration only when required.
Export an image already loaded or modified in the page Canvas → toDataURL() Remote pixels need CORS approval; canvas export may change the image.
Handle large rendered output Canvas → toBlob() A Blob and object URL avoid assembling a large data URL string in memory.

Reliability, memory, and security considerations

Check status before reading bytes

fetch() resolves for HTTP error responses, so always test response.ok. Without that check, a 404 page or an access-denied response may be encoded as if it were an image.

Validate what you received

For uploads or API forwarding, inspect blob.type and, where appropriate, enforce an allow-list of image MIME types. A URL ending in .jpg is not proof that the response is a JPEG. Also apply an application-specific size limit before converting or storing data.

Remember that data URLs expose their contents

Anyone who can read the resulting string can read the image. Do not place private images in a data URL embedded in public HTML, logs, analytics events, or URLs. Base64 is an encoding, not encryption.

Avoid unnecessary conversions

If the destination accepts a Blob, ArrayBuffer, or multipart upload, sending the original Blob is usually simpler than creating a data URL and then stripping its prefix. Convert only when the receiving interface specifically requires Base64 or a data URL.

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

Common errors and fixes

“Failed to fetch” or a CORS error

The browser could not read the cross-origin response. Configure CORS on the image host, use an endpoint under your control, or perform the request on a server. A successful display in an <img> tag does not change this requirement.

The function returns an HTML document

The URL may redirect to a sign-in page, anti-bot challenge, or error document. Inspect the status, final URL, response headers, and blob.type before treating the result as an image.

Canvas throws SecurityError

The canvas is tainted by pixels from a source that did not grant CORS access. Set crossOrigin before src and obtain the correct response headers; otherwise canvas export is intentionally blocked.

The Base64 string is rejected by an API

Check whether the API wants a complete data URL or only the payload. Use dataUrl for the former and dataUrlToBase64(dataUrl) for the latter. Also verify that the MIME type and the API’s size limits match the image you sent.

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

The page becomes slow or runs out of memory

Large data URLs require a large in-memory string. Prefer Blob-based uploads or canvas toBlob(), release object URLs with URL.revokeObjectURL(), and avoid keeping duplicate strings in state, logs, and DOM attributes.

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 what you really need is a clean screenshot of a webpage before converting or embedding the resulting image, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed, while bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the outcome with X-Page-Verdict and X-Billed headers.

Use the API details and options in the ScreenshotNeo documentation. A cURL request is:

curl -G 'https://api.screenshotneo.com/v1/shot' -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in JavaScript is:

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 request failed: ${res.status}`);
const screenshotBlob = await res.blob();
const screenshotDataUrl = await new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.onload = () => resolve(reader.result);
  reader.onerror = () => reject(reader.error);
  reader.readAsDataURL(screenshotBlob);
});

Python and Node.js callers can save the response directly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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)
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 request failed: ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

ScreenshotNeo also provides an MCP server for Claude, Cursor, and other MCP clients, plus full-page capture with lazy images loaded, CSS-selector element capture, device presets, retina scale, PDF controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage data, and an OpenAPI specification. Every feature is included on every plan. The free plan includes 1,000 shots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Server-side JavaScript is a separate case

The code above relies on browser Web APIs and specifically addresses browser CORS behavior. A Node.js process does not automatically follow the same browser security model, but its HTTP, Blob, and file APIs vary by Node version and project setup. Choose an implementation for the exact runtime and test its response handling, MIME validation, memory use, and redirect policy rather than copying a browser recipe unchanged.

Frequently Asked Questions

Does Base64 reduce an image’s file size?

No. Base64 is a text encoding and is generally less compact than the original binary bytes. Use it for compatibility with an interface that requires text, not as a compression method.

Can I put a Base64 image in CSS?

Yes, when the CSS property accepts a URL, a complete data URL can be used with syntax such as background-image: url('data:image/png;base64,...'). Keep the MIME declaration and consider the memory and caching consequences for large images.

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

Why does my data URL contain a different MIME type than the file extension?

The MIME declaration comes from the response Blob or the canvas export type, not from the URL’s filename. Check the server response and request the output format you actually need.

Is a data URL permanent?

The string remains usable as long as you retain it, but it is not a hosted backup. Store the original bytes or an image URL when you need durable storage, access control, or efficient caching.

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
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

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.