问题
So I've been working on a fun, online image effect program in javascript where the user enters a url to an image and hits 'enter', the image is drawn on the screen, and then the user can run some effects on it, such as g for greyscale, b for blur, etc.
My problem is that the console prints out either:
Redirect at origin [origin] has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
or:
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
I looked into many answers to this issue, and I added an extension to my chrome browser that enables cross-origin resource sharing, and my webpage runs fine (after a couple of reloads).
All the solutions I found require either enabling the cross-origin resource sharing option in chrome, or using some sort of php and ajax calls to enable this option. Since I'm writing the code on jsbin, I'm looking specifically for a solution that can be done in pure javascript, and I haven't been able to find any that work. If you have any ideas on something that could work, or the news that there is no possible solution, any response would be appreciated.
My code:
var background, context, image;
var docwidth, docheight;
image = new Image();
image.src = $('#image-src').val();
image.crossOrigin = "anonymous";
docwidth = $(document).outerWidth(true);
docheight = $(document).outerHeight(true);
background = document.getElementById("background");
context = background.getContext("2d");
image.onload = function() {
background.width = docwidth;
background.height = docheight;
context.drawImage(image,0,0,image.width,image.height, 0, 0, docwidth, docheight);
};
function change_image_src(src) {
image.src = $('#image-src').val();
}
// ... more image effect functions ...
function grayscale() {
var data = context.getImageData(0, 0, background.width, background.height);
var pixels = data.data;
for (var x = 0; x < data.width; x++)
for (var y = 0; y < data.height; y++) {
var i = (y * 4) * data.width + x * 4;
var avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
pixels[i] = avg;
pixels[i + 1] = avg;
pixels[i + 2] = avg;
}
context.putImageData(data, 0, 0, 0, 0, data.width, data.height);
}
$(document).keydown(function(e) {
switch (e.which) {
// ... other cases ...
case 71: // g
grayscale();
break;
}
});
Btw, I do have image.crossOrigin = "anonymous";
Thanks in advance!
回答1:
In order to use images from another origin on a canvas without tainting it, the image must be served with CORS headers. This page on MDN explains it, but essentially, when the image is served, it has to be accompanied by an Access-Control-Allow-Origin
header allowing the origin of your page (potentially via the *
wildcard).
Unless the image is served that way, putting it in the canvas will taint it, and you won't be able to use getImageData
.
So this isn't a JavaScript thing, really; it's how the image is served that determines how you can use it.
回答2:
I was able to get over this problem using a CORS proxy server: http://crossorigin.me/
来源:https://stackoverflow.com/questions/32558374/allow-access-control-allow-origin-in-pure-javascript