How to Fix "The canvas has been tainted by cross-origin data" Errors

Published: Thursday, June 16, 2022
Updated: Saturday, June 18, 2022

Greetings, friends! Has this ever happened to you? You're working with the HTML Canvas API, having the time of your life, but then you get an unexpected error:

text
Copied! ⭐️
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

Ugh! This error just spoiled your fun! In this tutorial, I will discuss how to resolve this issue!

Let's use CodePen to create a new "Pen" where we can test out some HTML, CSS, and JavaScript code. I'm guessing they got the name, "pen," from the word, "playpen" 🤔. Anyhoo, let's insert the following in the HTML section of our Pen.

html
Copied! ⭐️
<canvas id="canvas" width="1000" height="535"></canvas>

In the CSS section, insert the following:

css
Copied! ⭐️
#canvas {
  border: 1px solid black;
}

This border just lets us see where the canvas is, so we can make sure things the canvas is rendering properly. Next, we'll insert the following JavaScript code to fetch an image from a remote server.

javascript
Copied! ⭐️
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const image = new Image();
image.src = 'https://images.pexels.com/photos/12043242/pexels-photo-12043242.jpeg';

image.onload = () => {
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
};

CodePen will make a request to an external website when the code is run. It will grab a free stock photo from Pexels. Our code will then draw this image to the canvas.

Photo of green grass field near mountain under white clouds by Gleb Lucky on pexels.com

So far, so good! Now, what might happen if we were to make this image "dirty" or "tainted?" By that, I mean we alter the pixel values of the canvas, so they're different from the original. Let's make a removeRed function that removes all red pixels from the canvas.

javascript
Copied! ⭐️
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const image = new Image();
image.src = "https://images.pexels.com/photos/12043242/pexels-photo-12043242.jpeg";

image.onload = () => {
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  removeRed();
};

const removeRed = () => {
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  for (let i = 0; i < data.length; i += 4) {
    data[i] = 0; // remove red color from each pixel
  }
  ctx.putImageData(imageData, 0, 0);
};
tip
If you're reading this much later than this article's original publication date, you may need to choose a different URL or copy the image address of the image I use on this website.

When we run this code, you'll see that nasty error appear. The canvas has been tainted by cross-origin data.

Screenshot of CodePen. Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

As a security precaution, the browser will warn you that the canvas has been tainted. This protects users from having private data exposed from images that pull information from remote servers without permission. Hackers are very crafty! You never know what new diabolical methods they'll come up with!

To fix this problem, we need to allow cross-origin use of images and the canvas. This one line will solve the issue!

javascript
Copied! ⭐️
image.crossOrigin = "Anonymous";

This line will allow non-authenticated downloading of the image cross-origin (between different websites or subdomains). In a real production app, you'd only do this if you trust the website you're pulling resources from. Once we add this line to our code, we end up with the following:

javascript
Copied! ⭐️
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const image = new Image();
image.src = "https://images.pexels.com/photos/12043242/pexels-photo-12043242.jpeg";
image.crossOrigin = "Anonymous";

image.onload = () => {
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  removeRed();
};

const removeRed = () => {
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  for (let i = 0; i < data.length; i += 4) {
    data[i] = 0; // remove red color from each pixel
  }
  ctx.putImageData(imageData, 0, 0);
};

When the code runs, you should see the original image but with the red removed! So pretty! 😲

Edited photo of green grass field near mountain under white clouds by Gleb Lucky on pexels.com. The red color has been removed, resulting in light blue clouds and saturated green grass.

If you still get an error about the canvas being tainted by cross-origin data, then this issue could be on the server side. The server must be configured to host images with the Access-Control-Allow-Origin header configured to permit cross-origin access to image files.