Поведение "Происхождение" недопустимо по ошибке Access-Control-Allow-Origin

img = new Image();

img.crossOrigin = "anonymous";

try {
    cimg.src = document.getElementById("url").value;
}
catch(err) {
    alert("Cannot access image.Cross-Domain access blocked");
};

Итак, я хочу обнаружить/поймать ошибку междоменного доступа.

После некоторой мысли я узнал, что загрузка src является асинхронной, и, следовательно, блок catch не будет работать. Есть ли способ обнаружить ошибку, чтобы я мог эффективно ее обрабатывать?

Ответы

Ответ 1

Как отметил @TamasHegedus, изображение все еще может быть загружено с ошибкой CORS, но это не позволяет манипулировать данными изображения. Это означает, что вы можете использовать холст, чтобы попытаться манипулировать изображением и поймать любые брошенные ошибки.

Этот метод будет работать для изображений с поддержкой canvas. См. @Kaiido ответ, если вам нужна более простая альтернатива с помощью Image#crossOrigin. Его решение также определяет, поддерживается ли свойство, и при необходимости использует холст.

// 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.stack.imgur.com/Kt3vI.png?s=48&g=1';

Ответ 2

В браузерах, поддерживающих запросы CrossOrigin (которые должны быть предпочтительными), если вы установите crossOrigin в 'anonymous' и попробуйте установить элемент src, указывая на файл, размещенный на некорректно настроенном сервере, событие load не будет запускаться, и вместо этого произойдет событие error.

Важно понимать, что в случае неудавшегося запроса CrossOrigin сервер ответит напрямую, что он не принимает запрос, поэтому между вашим пользователем и удаленным сервером отправляются только заголовки, а другой путь (сначала попробуйте без запроса crossOrigin, затем попробуйте), вы должны сначала скачать полностью * ресурс, а затем загрузить его снова с помощью атрибута crossOrigin...

То же самое относится к запросам аудио, видео и xhr.

Итак, сначала нужно установить crossOrigin запросов с кросс-началом, а затем, если он не работает, это означает, что другая рука неправильно настроена.

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.stack.imgur.com/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");
    }
 }