Как правило, у команд есть специальное доменное имя для размещения статических ресурсов, например gtimg.com от Tencent и bdimg.com от Baidu, или многие команды используют сервисы Tencent Cloud или Alibaba Cloud;
Доменные имена главных страниц часто различаются. Когда необходимо выполнить операции getImageData() или toDataURL() с изображениями холста, возникают междоменные проблемы, причем существует более одного уровня междоменных проблем.
Во-первых, на первом этапе серверу изображений необходимо настроить информацию Access-Control-Allow-Origin, например:
Например, PHP добавляет информацию заголовка ответа, а подстановочный знак * указывает, что разрешено любое доменное имя:
заголовок (Access-Control-Allow-Origin: *);
Или укажите доменное имя:
заголовок (Access-Control-Allow-Origin: www.zhangxinxu.com);
В настоящее время в браузере Chrome больше не будет сообщений об ошибках, связанных с Access-Control-Allow-Origin, но появятся другие междоменные сообщения об ошибках.
2. Проблема междоменного изображения с изображением холста getImageData из разных источниковМеждоменные изображения, если они могут нормально отображаться на веб-странице, могут быть нарисованы с помощью API drawImage() холста. Но если вы хотите пойти еще дальше и получить полную информацию о пикселях изображения с помощью метода getImageData(), вы, вероятно, допустите ошибку.
Например, используйте следующий код, чтобы получить информацию о своем собственном изображении аватара на github:
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.onload = function () { context.drawImage(this, 0, 0) ; context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
В результате в браузере Chrome отображается следующая ошибка:
Неперехваченное исключение DOMException: не удалось выполнить getImageData для CanvasRenderingContext2D: холст испорчен данными из разных источников.
Ошибка браузера Firefox:
SecurityError: операция небезопасна.
Если используется метод Canvas.toDataURL(), он сообщит:
Не удалось выполнить toDataURL для HTMLCanvasElement: испорченный холст не может быть экспортирован.
Причины на самом деле те же, вызванные кросс-доменом.
Так есть ли способ решить эту проблему?
Вы можете попробовать атрибут CrossOrigin.
3. Атрибут HTML CrossOrigin решает междоменную проблему ресурсов.В HTML5 некоторые элементы предоставляют атрибуты, поддерживающие CORS (совместное использование ресурсов между источниками) (совместное использование ресурсов между источниками). К этим элементам относятся <img>, <video>, <script> и т. д., а указанное имя атрибута — это имя. Атрибут CrossOrigin.
Следовательно, описанную выше междоменную проблему можно решить следующим образом:
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (this, 0, 0); context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Просто добавьте img.crossOrigin = ''. Хотя код JS здесь устанавливает пустую строку, фактическое значение атрибута является анонимным.
CrossOrigin может иметь следующие два значения:
Ключевые слова | Определение |
---|---|
анонимный | Запросы ресурсов между источниками для элементов не требуют установки флага учетных данных. |
учетные данные использования | Запросы междоменных ресурсов для элементов требуют установки флага учетных данных, что означает, что для запроса необходимы учетные данные. |
Среди них, пока значение атрибута crossOrigin не является use-credentials, все будет анализироваться как анонимное, включая пустые строки, включая такие символы, как «abc».
Например:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // Результат - "анонимный";
Еще следует отметить, что, хотя атрибута crossOrigin нет, а установка crossOrigin=use-credentials по умолчанию будет сообщать о междоменной ошибке, они различны по своей природе, и между ними существует большая разница.
совместимость с CrossOriginБраузеры IE11+ (IE Edge), Safari, Chrome и Firefox поддерживают его. IE9 и IE10 сообщают об ошибке безопасности, как показано на снимке экрана ниже:
4. Почему атрибут crossOrigin может решить проблему междоменных ресурсов?crossOrigin=anonymous Вместо того, чтобы сообщать другому серверу, вам не нужно сообщать какую-либо неанонимную информацию. Например, файлы cookie, поэтому текущий браузер определенно безопасен.
Точно так же, как вы хотите пойти в чужой дом, чтобы забрать предмет одежды, crossOrigin=anonymous отличается от сообщения другому человеку: «Мне нужна только одежда и ничего больше». Если вы не сообщите им об этом, собеседник может положить подслушивающее устройство или что-то еще в их одежду, что будет небезопасно, и браузер заблокирует это.
5. Что делать, если браузер IE10 не поддерживает CrossOrigin?Когда мы запрашиваем изображения, мы не используем new Image() напрямую, а используем ajax и метод URL.createObjectURL() для сохранения страны.
Код выглядит следующим образом:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); Вы можете использовать холст, чтобы делать с img // ... код ... // Не забудьте освободить память после использования изображения URL.revokeObjectURL(url }); = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
Этот метод подходит не только для браузера IE10, но также поддерживается всеми браузерами, которые изначально поддерживали CrossOrigin.
Для этого требуется всего лишь еще один запрос ajax, и это нормально!
Согласно практике, в браузере IE, если запрошенное изображение слишком велико, в несколько тысяч пикселей, изображение не сможет загрузиться, я думаю, оно превышает предел размера большого двоичного объекта.
6. ЗаключениеНедавно я получил небольшой опыт на работе, надеюсь, он поможет друзьям, столкнувшимся с аналогичными проблемами. Я также надеюсь, что все поддержат сеть VeVb Wulin.