Должна ли установка src изображения для URL-адреса данных быть доступной немедленно?

Рассмотрим следующий (хрупкий) код JavaScript:

var img = new Image;
img.src = "data:image/png;base64,..."; // Assume valid data

// Danger(?) Attempting to use image immediately after setting src
console.log( img.width, img.height );
someCanvasContext.drawImage( img, 0, 0 );

// Danger(?) Setting onload after setting src
img.onload = function(){ console.log('I ran!'); };

Вопрос (ы)

  • Следует ли сразу изменять ширину и высоту изображения?
  • Следует ли рисовать на холсте немедленно?
  • Следует ли вызвать обратный вызов onload (установленный после изменения src)?

Экспериментальные тесты
Я создал простую тестовую страницу с аналогичным кодом. В Safari мои первые тесты, открыв HTML-страницу локально ( file: /// url) и загрузив ее с моего сервера, показали, что все работает: высота и ширина правильные, отрисовка холста работает, и onload также срабатывает.

В Firefox v3.6 (OS X) загрузка страницы после запуска браузера показывает, что высота / ширина неверны сразу после установки , drawImage () не работает. (Однако обработчик onload срабатывает.) Однако повторная загрузка страницы показывает, что ширина / высота правильные сразу после установки, а drawImage () работает. Похоже, что Firefox кэширует содержимое URL-адреса данных как изображение и сразу же делает его доступным при использовании в том же сеансе.

В Chrome v8 (OS X) я вижу те же результаты, что и в Firefox: изображение не доступны немедленно, но для асинхронной «загрузки» из URL-адреса данных требуется некоторое время.

В дополнение к экспериментальному доказательству того, какие браузеры работают или не работают, мне бы очень хотелось получить ссылки на спецификации о том, как это должно вести себя. Пока мой гугл-фу не справлялся с этой задачей.

Безопасная игра
Для тех, кто не понимает, почему вышеперечисленное может быть опасным, знайте, что вы должны использовать такие изображения, чтобы быть в безопасности:

// First create/find the image
var img = new Image;

// Then, set the onload handler
img.onload = function(){
  // Use the for-sure-loaded img here
};

// THEN, set the src
img.src = '...';

71
задан Phrogz 25 April 2012 в 19:01
поделиться