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, показанный ниже:

xml
<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, в который будет загружено изображение. Это сообщает браузеру запросить доступ к ресурсам из другого домена при загрузке данных изображения.

Запуск загрузки

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

js
function startDownload() {
  let imageURL =
    "https://cdn.glitch.com/4c9ebeb9-8b9a-4adc-ad0a-238d9ae00bb5%2Fmdn_logo-only_color.svg?1535749917189";
  let imageDescription = "The Mozilla logo";

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

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

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

Приём и сохранение изображения

Код, обрабатывающий загруженное изображение, находится в методе imageReceived():

js
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}`);
  }
}

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

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

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

См. также

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

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

Spec-Zone.ru

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