From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- files/ru/web/html/cors_enabled_image/index.html | 118 ++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 files/ru/web/html/cors_enabled_image/index.html (limited to 'files/ru/web/html/cors_enabled_image') diff --git a/files/ru/web/html/cors_enabled_image/index.html b/files/ru/web/html/cors_enabled_image/index.html new file mode 100644 index 0000000000..7f856ba8af --- /dev/null +++ b/files/ru/web/html/cors_enabled_image/index.html @@ -0,0 +1,118 @@ +--- +title: Разрешение использования изображений из разных источников и canvas +slug: Web/HTML/CORS_enabled_image +tags: + - Advanced + - Canvas + - HTML + - Reference + - Security +translation_of: Web/HTML/CORS_enabled_image +--- +

HTML предоставляет атрибут {{ htmlattrxref("crossorigin", "img") }} для изображений, которые в сочетании с соответствующим заголовком {{Glossary("CORS")}} позволяют использовать изображения, определённые элементом {{ HTMLElement("img") }}, загруженные из внешних источников, в {{HTMLElement("canvas")}} , как если бы они были загружены из текущего источника.

+ +

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

+ +

Безопасность и испорченные холсты canvas

+ +

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

+ +

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

+ +

Если источником внешнего содержимого является элемент HTML {{HTMLElement("img")}} или SVG {{SVGElement("svg")}}, то попытка извлечения содержимого холста не допускается.

+ +

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

+ +

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

+ + + +

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

+ +

Хранение изображений из внешнего источника

+ +

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

+ +

Конфигурация веб-сервера

+ +

Первое, что нам нужно, - это сервер, настроенный на размещение изображений с заголовком {{HTTPHeader("Access-Control-Allow-Origin")}}, настроенным на разрешение доступа к файлам изображений из разных источников.

+ +

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

+ +
<IfModule mod_setenvif.c>
+  <IfModule mod_headers.c>
+    <FilesMatch "\.(bmp|cur|gif|ico|jpe?g|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") для получения доступа из любой точки интернета.

+ +

Реализация возможности сохранения

+ +

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

+ +

Ключевым моментом является использование атрибута {{htmlattrxref("crossorigin")}} путем установки {{domxref("HTMLImageElement.crossOrigin", "crossOrigin")}}  в элементе {{domxref("HTMLImageElement")}} , на который будет загружено изображение. Это даёт браузеру команду на запрос доступа к другому источнику при попытке загрузить данные изображения.

+ +

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

+ +

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

+ +
function startDownload() {
+  let imageURL = "https://cdn.glitch.com/4c9ebeb9-8b9a-4adc-ad0a-238d9ae00bb5%2Fmdn_logo-only_color.svg?1535749917189";
+
+  downloadedImg = new Image;
+  downloadedImg.crossOrigin = "Anonymous";
+  downloadedImg.addEventListener("load", imageReceived, false);
+  downloadedImg.src = imageURL;
+}
+ +

Здесь мы используем жёстко закодированный URL-адрес (imageURL), но он запросто может поступать откуда угодно. Чтобы начать загрузку изображения, мы создаём новый объект {{domxref("HTMLImageElement")}} с помощью конструктора {{domxref("HTMLImageElement.Image", "Image()")}}. Затем изображение настраивается так, чтобы разрешить загрузку из другого источника. Для этого его атрибут crossOrigin устанавливается на "Anonymous" (то есть разрешение неавторизованной загрузки изображения из перекрёстного источника). Прослушиватель событий добавляется к событию {{event("load")}}, запускаемому на элементе изображения, что означает, что данные изображения были получены.

+ +

Наконец, атрибут {{domxref("HTMLImageElement.src", "src")}} изображения устанавливается в URL-адрес загружаемого изображения; это инициирует начало загрузки.

+ +

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

+ +

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

+ +
function imageReceived() {
+  let canvas = document.createElement("canvas");
+  let context = canvas.getContext("2d");
+
+  canvas.width = downloadedImg.width;
+  canvas.height = downloadedImg.height;
+
+  context.drawImage(downloadedImg, 0, 0);
+  imageBox.appendChild(canvas);
+
+  try {
+    localStorage.setItem("saved-image-example", canvas.toDataURL("image/png"));
+  }
+  catch(err) {
+    console.log("Error: " + err);
+  }
+}
+ +

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

+ +

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

+ +

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

+ +

Вы можете проверить или переделать этот пример на Glitch.

+ +

Смотрите также

+ + + +
{{QuickLinksWithSubpages("/en-US/docs/Web/HTML/")}}
-- cgit v1.2.3-54-g00ecf