Generalmente, los equipos tendrán un nombre de dominio especial para colocar recursos estáticos, por ejemplo, Tencent es gtimg.com, Baidu es bdimg.com o muchos equipos usan los servicios Tencent Cloud o Alibaba Cloud;
Los nombres de dominio de las páginas principales suelen ser diferentes. Cuando es necesario realizar operaciones getImageData () o toDataURL () en imágenes de lienzo, surgen problemas entre dominios y hay más de un nivel de problemas entre dominios.
Primero, en el primer paso, el servidor de imágenes necesita configurar la información de Acceso-Control-Permitir-Origin, por ejemplo:
Por ejemplo, PHP agrega información del encabezado de respuesta y el comodín * indica que se permite cualquier nombre de dominio:
encabezado(Acceso-Control-Permitir-Origen: *);
O especifique un nombre de dominio:
encabezado (Acceso-Control-Permitir-Origen: www.zhangxinxu.com);
En este punto, el navegador Chrome ya no tendrá mensajes de error relacionados con Access-Control-Allow-Origin, pero habrá otros mensajes de error entre dominios.
2. Problema de dominio cruzado de origen cruzado getImageData de imagen de lienzoPara imágenes de dominios cruzados, siempre que se puedan mostrar normalmente en la página web, se pueden dibujar usando la API drawImage () de Canvas. Pero si quieres ir un paso más allá y obtener la información completa de píxeles de la imagen mediante el método getImageData(), probablemente cometas un error.
Por ejemplo, utilice el siguiente código para obtener la información de su propia imagen de avatar en github:
var lienzo = document.createElement('canvas');var contexto = lienzo.getContext('2d');var img = nueva Imagen();img.onload = función () { contexto.drawImage(this, 0, 0) ; contexto.getImageData(0, 0, este.ancho, este.alto);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';El resultado es el siguiente error que se muestra en el navegador Chrome:
DOMException no detectada: no se pudo ejecutar 'getImageData ' en 'CanvasRenderingContext2D ': el lienzo se ha visto contaminado por datos de origen cruzado.
El error del navegador Firefox es:
SecurityError: La operación es insegura.
Si se utiliza el método canvas.toDataURL(), informará:
No se pudo ejecutar 'toDataURL ' en 'HTMLCanvasElement ': el lienzo contaminado no se puede exportar
Las razones son en realidad las mismas, causadas por dominios cruzados.
Entonces, ¿hay alguna forma de solucionar este problema?
Puedes probar el atributo crossOrigin.
3. El atributo HTML crossOrigin resuelve el problema de recursos entre dominiosEn HTML5, algunos elementos proporcionan atributos que admiten CORS (intercambio de recursos entre orígenes) (intercambio de recursos entre orígenes). Estos elementos incluyen <img>, <video>, <script>, etc., y el nombre del atributo proporcionado es el. atributo origen cruzado.
Por lo tanto, el problema entre dominios anterior se puede manejar de la siguiente manera:
var canvas = document.createElement('canvas');var context = canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (esto, 0, 0); contexto.getImageData(0, 0, este.ancho, este.alto);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';Simplemente agregue un img.crossOrigin = ''. Aunque el código JS aquí establece una cadena vacía, el valor del atributo real que funciona es anónimo.
crossOrigin puede tener los dos valores siguientes:
| Palabras clave | Definición |
|---|---|
| anónimo | Las solicitudes de recursos de orígenes cruzados para elementos no requieren que se establezca el indicador de credenciales. |
| usar-credenciales | Las solicitudes de recursos entre dominios para elementos requieren que se establezca el indicador de credenciales, lo que significa que se requieren credenciales para la solicitud. |
Entre ellos, siempre que el valor del atributo de crossOrigin no sea use-credentials, todo se analizará como anónimo, incluidas las cadenas vacías y caracteres como "abc".
Por ejemplo:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // El resultado es 'anónimo'
Otra cosa a tener en cuenta es que, aunque no existe un atributo crossOrigin y configurar crossOrigin = use-credentials informará un error entre dominios de forma predeterminada, hay una gran diferencia entre los dos.
compatibilidad entre orígenesLos navegadores IE11+ (IE Edge), Safari, Chrome y Firefox lo admiten. IE9 e IE10 informarán un error de seguridad, como se muestra en la siguiente captura de pantalla:
4. ¿Por qué el atributo crossOrigin puede resolver el problema de los recursos entre dominios?crossOrigin=anonymous En lugar de informarle al otro servidor, no es necesario que proporcione ninguna información no anónima. Por ejemplo, las cookies, por lo que el navegador actual es definitivamente seguro.
Es como si quisieras ir a la casa de alguien a recoger una prenda de vestir. crossOrigin=anonymous es diferente a decirle a la otra persona que solo quiero la ropa y nada más. Si no se lo dice, la otra parte puede poner un dispositivo de escucha o algo en su ropa, lo que no será seguro y el navegador lo bloqueará.
5. ¿Qué debo hacer si el navegador IE10 no es compatible con crossOrigin?Cuando solicitamos imágenes, no usamos directamente new Image(), sino que usamos ajax y el método URL.createObjectURL() para guardar el país.
El código es el siguiente:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); Puedes usar canvas para hacer lo que quieras con img // ... code ... // Recuerda liberar la memoria después de usar la imagen URL.revokeObjectURL(url }; = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();Este método no solo es válido para el navegador IE10, sino que también es compatible con todos los navegadores que originalmente admitían crossOrigin.
Solo requiere una solicitud ajax más, ¡lo cual está bien!
Según la práctica, en el navegador IE, si la imagen solicitada es demasiado grande, unos pocos miles de píxeles, la imagen no se cargará, supongo que excede el límite de tamaño del blob.
6. ConclusiónRecientemente aprendí una pequeña experiencia en el trabajo, espero que pueda ayudar a amigos que enfrentan problemas similares. También espero que todos apoyen la red VeVb Wulin.