I'm trying to figure out how to get an image from an image URL from other domains to then post to my server. But I'm running into issues with cores.
I'm making a wishlist page where the user can enter a url for a product from any site. My server scrapes the URL for product information and product images and sends it to the client. The user refines the information and selects the desired image. This information is sent to the backend to create a wishlist item with product information and an image of the item.
Scraping product image & product info
Image and information goes on wishlist
Tainted Canvas
I tried to use the canvas to grab and crop the image and send it to my backend. But when you draw into a canvas an image loaded from another origin without CORS approval, the canvas becomes tainted.
Calling any of the following on a tainted canvas will result in an error:
- Calling
getImageData()
on the canvas's context- Calling
toBlob()
on the element itself- Calling
toDataURL()
on the canvas
export async function toDataURLCanvas(src, outputFormat) {
return new Promise((resolve) => {
const img = new Image();
img.onload = async function () {
console.log(this);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 200;
ctx.drawImage(this, 0, 0); //this is where you would crop the image
const blob = await new Promise((resolve) => {
// results in "Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.""
canvas.toBlob((blob) => {
resolve(blob);
}, 'image/jpg');
});
resolve(blob);
};
img.src = src;
});
}
This gives an error:
Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.
So I cannot use canvas to convert to image URL into a format to send to my backend such as a blob.
XHR
I tried to convert the URL to a data URL with XMLHttpRequest()
async function toDataURLXHR(url) {
return new Promise((resolve) => {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
resolve(reader.result);
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
});
}
But then CORS can be an issue. I got this in the browser console:
Access to XMLHttpRequest at 'https://cdn-images.farfetch-contents.com/15/40/82/30/15408230_28680969_600.jpg' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Not Possible?
It seems like it's not possible to grab an image from one site and send it to my server. But I've seen other sites do this so there must be a way.