img = new Image();
img.crossOrigin = "anonymous";
try {
cimg.src = document.getElementById("url").value;
}
catch(err) {
alert("Cannot access image.Cross-Domain access blocked");
};
So, i want to detect/catch Cross-Domain access blocked error.
After some thought i found out that it src loading is async & thus the catch block wont work. Is there any way to detect the error so i can handle it efficiently?
img = new Image();
img.crossOrigin = "anonymous";
try {
cimg.src = document.getElementById("url").value;
}
catch(err) {
alert("Cannot access image.Cross-Domain access blocked");
};
So, i want to detect/catch Cross-Domain access blocked error.
After some thought i found out that it src loading is async & thus the catch block wont work. Is there any way to detect the error so i can handle it efficiently?
Share Improve this question edited Feb 2, 2019 at 10:18 sideshowbarker♦ 88.2k29 gold badges215 silver badges211 bronze badges asked Sep 2, 2016 at 13:56 Debanjan DharDebanjan Dhar 4181 gold badge6 silver badges12 bronze badges 4- 7 You can load cross-origin image, you just cant read their pixels. So a cors error will never happen during img load. – Tamas Hegedus Commented Sep 2, 2016 at 14:06
- 1 So, in essence cors happens after image load? Well how do i detect cors after img load them? :$ I need to differentiate between the cors & img load fail due to bad url – Debanjan Dhar Commented Sep 2, 2016 at 14:13
-
2
@DebanjanDhar - to clarify, you want to check if the image you load CAN be "manipulated" not just a resource being shown in an
<img>
or<object>
tag. Is that correct? – Jaromanda X Commented Sep 2, 2016 at 14:15 - @JaromandaX Yes – Debanjan Dhar Commented Sep 2, 2016 at 14:16
2 Answers
Reset to default 12As @TamasHegedus mented, the image can still be loaded with the CORS error, but it doesn't allow the image data to be manipulated. That means you can use the canvas to try to manipulate the image and catch any thrown errors.
This technique would work for canvas-supported images. See @Kaiido's answer if you want a simpler alternative using the Image#crossOrigin
property. His solution also detects whether the property is supported and uses canvas when necessary.
// Must work in IE9+.
var img = new Image;
img.onload = function() {
var canvas = document.createElement('canvas');
// resize the canvas, else img won't be rendered
canvas.width = img.width;
canvas.height = img.height;
// get the canvas rendering context 2d
var ctx = canvas.getContext('2d');
// draw the image first
ctx.drawImage(img, 0, 0);
try {
/* get first pixel */
ctx.getImageData(0, 0, 1, 1);
/* no error catched – no cors error */
alert("Cross-domain access available.");
} catch (e) {
alert("Cross-domain access blocked.");
}
};
img.src = 'https://i.sstatic/Kt3vI.png?s=48&g=1';
In browsers supporting crossOrigin requests, (which should be preferred ones), if you set the crossOrigin
to 'anonymous'
, and try to set your element's src
pointing to a file hosted on a improperly set-up server, the load
event won't fire, and instead, an error
event will.
It is important to understand that in the case of a failed crossOrigin request, the server will answer directly that it doesn't accept the request, so only headers are sent between your user and the distant server, while doing the other way around (first try without the crossOrigin request, then try with), you have to first download entirely* the resource , then download it again with the crossOrigin attribute set...
Same applies for audio, video, and xhr requests.
So one should first set the crossOrigin of cross-origin requests, then if it fails it means that the other hand is not properly configured.
var img = new Image();
if('crossOrigin' in img){
// an up to date browser
// make a single crossOrigin request
img.crossOrigin = 'anonymous';
img.onerror = handleCORSFailure;
}
else{
// for browser that don't support the crossOrigin request
var ctx = document.createElement('canvas').getContext('2d');
ctx.width = ctx.height = 1; // no need to use too much memory, 1*1 px is enough
img.addEventListener('load', function(){
ctx.drawImage(this,0,0);
try{
ctx.getImageData(0,0,1,1);
}
catch(e){
handleCORSFailure(e);
return;
}
});
}
img.src = 'https://i.sstatic/Kt3vI.png?s=48&g=1';
function handleCORSFailure(e){
if(e.target){
console.log('server not set correctly');
}
else{
console.log("browser doesn't support crossOrigin requests");
}
}
-* Actually, only images need to be downloaded entirely, all other resources can be tested before the end.
Ps : in case of same-origin request, the crossOrigin attribute should not hurt, so this check can still be performed.