I need to convert a remote image into base64 given its URL, but I am running in to CORS errors and not sure how to work around.
I've followed some of the solutions on this question: How to convert image into base64 string using javascript
My example image is: https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg
Approach 1 (FileReader):
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );
This produces the error:
XMLHttpRequest cannot load https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://stackoverflow.com' is therefore not allowed access.
Approach 2 (Canvas)
function toDataUrl(src, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'use-credentials';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
};
img.src = src;
if (img.complete || img.complete === undefined) {
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
img.src = src;
}
}
toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );
Produces a similar error when trying to load the image:
Access to Image at 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg' from origin 'http://stackoverflow.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://stackoverflow.com' is therefore not allowed access.
Also tried with:
img.crossOrigin = 'anonymous';
And got the same result.
Approach 3 (Canvas using img element):
img = document.createElement('img');
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL('image/jpg');
console.log(dataURL);
};
img.src = 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg';
This way at least loads the image but fails on calling toDataURL with:
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at HTMLImageElement.img.onload (:9:22)
As an aside, I'm not sure exactly what the CORS policy is protecting against here. Suppose there is some kind of malicious payload that could trigger an exploit. We still load and display the image in the DOM and why would we trust CORS headers set by the same endpoint?
Does anyone know of any solutions to this problem?
Thanks for any help.