Spec-Zone.ru › HTML

Использование изображений из другого источника на холсте

HTML предоставляет атрибут crossorigin для изображений, который в сочетании с соответствующим заголовком CORS позволяет использовать изображения, заданные элементом <img> и загруженные из внешних источников, в элементе <canvas> так, как если бы они были загружены с текущего источника.

Подробнее об использовании атрибута crossorigin см. в разделе Атрибуты настроек CORS.

Безопасность и загрязнённые холсты

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

Как только на холст добавляются какие-либо данные, загруженные из другого источника без разрешения CORS, холст становится загрязнённым. Загрязнённый холст больше не считается безопасным, и любая попытка получить из него данные изображения приведёт к возникновению исключения.

Если источником внешнего содержимого является HTML-элемент <img> или SVG-элемент <svg>, попытка получить содержимое холста запрещена.

Если внешнее содержимое поступает из изображения, полученного либо как HTMLCanvasElement, либо как ImageBitMap, и источник изображения не соответствует правилам единого источника, попытки прочитать содержимое холста блокируются.

Вызов любого из следующих методов для загрязнённого холста приведёт к ошибке:

  • Вызов getImageData() у контекста холста
  • Вызов toBlob(), toDataURL() или captureStream() непосредственно у элемента <canvas>

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

Сохранение изображения из внешнего источника

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

Настройка веб-сервера

Для начала нам понадобится сервер, настроенный для размещения изображений с заголовком Access-Control-Allow-Origin, который разрешает междоменные запросы к файлам изображений.

Предположим, что наш сайт обслуживается с помощью Apache. Рассмотрим файл конфигурации сервера Apache для изображений CORS из HTML5 Boilerplate, доступный по ссылке конфигурация сервера Apache для изображений CORS и приведённый ниже:

<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    <FilesMatch "\.(avifs?|bmp|cur|gif|ico|jpe?g|jxl|a?png|svgz?|webp)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS
    </FilesMatch>
  </IfModule>
</IfModule>

Вкратце, эта конфигурация разрешает получать графические файлы (с расширениями ".bmp", ".cur", ".gif", ".ico", ".jpg", ".jpeg", ".png", ".svg", ".svgz" и ".webp") из любого места в интернете.

Реализация функции сохранения

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

Главное — использовать атрибут crossorigin, задав crossOrigin для элемента HTMLImageElement, в который будет загружено изображение. Это указывает браузеру запросить доступ из другого источника при загрузке данных изображения.

Начало загрузки

Код, запускающий загрузку (например, при нажатии пользователем кнопки «Загрузить»), выглядит так:

function startDownload() {
  let imageURL = "https://mdn.github.io/shared-assets/images/examples/mdn.svg";
  let imageDescription = "Logo of a dinosaur in front of a map";

  downloadedImg = new Image();
  downloadedImg.crossOrigin = "anonymous";
  downloadedImg.addEventListener("load", imageReceived);
  downloadedImg.alt = imageDescription;
  downloadedImg.src = imageURL;
}

Здесь мы используем жёстко заданный URL (imageURL) и связанное с ним описание (imageDescription), но их можно получить откуда угодно. Чтобы начать загрузку изображения, мы создаём новый объект HTMLImageElement с помощью конструктора Image(). Затем для изображения разрешается загрузка из другого источника: атрибуту crossOrigin присваивается значение "anonymous" (то есть разрешается загрузка изображения из другого источника без аутентификации). Для события load, возникающего у элемента изображения, добавляется обработчик. Это событие означает, что данные изображения получены. Также изображению задаётся альтернативный текст; хотя <canvas> не поддерживает атрибут alt, это значение можно использовать для задания aria-label или внутреннего содержимого холста.

Наконец, атрибуту src изображения присваивается URL загружаемого изображения, что запускает загрузку.

Получение и сохранение изображения

Код обработки только что загруженного изображения находится в методе imageReceived():

function imageReceived() {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");

  canvas.width = downloadedImg.width;
  canvas.height = downloadedImg.height;
  canvas.innerText = downloadedImg.alt;

  context.drawImage(downloadedImg, 0, 0);
  imageBox.appendChild(canvas);

  try {
    localStorage.setItem("saved-image-example", canvas.toDataURL("image/png"));
  } catch (err) {
    console.error(`Error: ${err}`);
  }
}

Для обработки события "load" элемента HTMLImageElement, получающего загруженное изображение, вызывается imageReceived(). Это событие возникает, когда все загруженные данные становятся доступны. Сначала создаётся новый элемент <canvas>, который мы будем использовать для преобразования изображения в URL данных, а также получается доступ к контексту двумерного рисования холста (CanvasRenderingContext2D) в переменной context.

Размер холста подгоняется под полученное изображение, внутренний текст задаётся равным описанию изображения, после чего изображение рисуется на холсте с помощью drawImage(). Затем холст добавляется в документ, чтобы изображение стало видимым.

Теперь можно сохранить изображение локально. Для этого мы используем механизм локального хранилища из Web Storage API, доступный через глобальный объект localStorage. Метод холста toDataURL() преобразует изображение в URL данных формата data://, представляющий изображение PNG. Затем это значение сохраняется в локальном хранилище с помощью setItem().

См. также

  • Использование изображений из других доменов в WebGL и Chrome 13
  • Спецификация HTML — атрибут crossorigin
  • Web Storage API

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/How_to/CORS_enabled_image

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API