Geralmente, as equipes terão um nome de domínio especial para colocar recursos estáticos, por exemplo, Tencent é gtimg.com, Baidu é bdimg.com ou muitas equipes usam serviços Tencent Cloud ou Alibaba Cloud;
Os nomes de domínio das páginas principais geralmente são diferentes. Quando é necessário executar operações getImageData() ou toDataURL() em imagens de tela, surgem problemas entre domínios e há mais de um nível de problemas entre domínios.
Primeiramente, na primeira etapa, o servidor de imagem precisa configurar as informações de Access-Control-Allow-Origin, por exemplo:
Por exemplo, o PHP adiciona informações de cabeçalho de resposta e o curinga * indica que qualquer nome de domínio é permitido:
cabeçalho(Access-Control-Allow-Origin: *);
Ou especifique um nome de domínio:
cabeçalho (Access-Control-Allow-Origin: www.zhangxinxu.com);
Neste ponto, o navegador Chrome não terá mais mensagens de erro relacionadas ao Access-Control-Allow-Origin, mas haverá outras mensagens de erro entre domínios.
2. Problema de domínio cruzado de origem cruzada getImageData da imagem da telaPara imagens entre domínios, desde que possam ser exibidas normalmente na página da web, elas podem ser desenhadas usando a API drawImage() do canvas. Mas se você quiser dar um passo adiante e obter as informações completas dos pixels da imagem através do método getImageData(), provavelmente cometerá um erro.
Por exemplo, use o código a seguir para obter as informações da sua própria imagem de avatar no 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, esta.largura, esta.altura);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
O resultado é o seguinte erro exibido no navegador Chrome:
DOMException não capturado: falha ao executar 'getImageData' em 'CanvasRenderingContext2D': a tela foi contaminada por dados de origem cruzada.
O erro do navegador Firefox é:
SecurityError: A operação não é segura.
Se o método canvas.toDataURL() for usado, ele reportará:
Falha ao executar 'toDataURL' em 'HTMLCanvasElement': tela contaminada não pode ser exportada
Os motivos são, na verdade, os mesmos, causados por domínios cruzados.
Então, existe alguma maneira de resolver esse problema?
Você pode tentar o atributo crossOrigin.
3. O atributo HTML crossOrigin resolve o problema de recursos entre domíniosNo HTML5, alguns elementos fornecem atributos que suportam CORS (Cross-Origin Resource Sharing) (compartilhamento de recursos de origem cruzada. Esses elementos incluem <img>, <video>, <script>, etc., e o nome do atributo fornecido é o). atributo crossOrigin.
Portanto, o problema de vários domínios acima pode ser tratado assim:
var canvas = document.createElement('canvas');var context = canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (isto, 0, 0); context.getImageData(0, 0, esta.largura, esta.altura);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Basta adicionar img.crossOrigin = ''. Embora o código JS aqui defina uma string vazia, o valor real do atributo que funciona é anônimo.
crossOrigin pode ter os dois valores a seguir:
Palavras-chave | Definição |
---|---|
anônimo | As solicitações de recursos de origem cruzada para elementos não exigem que o sinalizador de credenciais seja definido. |
credenciais de uso | As solicitações de recursos entre domínios para elementos exigem que o sinalizador de credenciais seja definido, o que significa que as credenciais são necessárias para a solicitação. |
Entre eles, desde que o valor do atributo crossOrigin não seja use-credentials, tudo será analisado como anônimo, incluindo strings vazias, incluindo caracteres como 'abc'.
Por exemplo:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // O resultado é 'anônimo';
Outra coisa a observar é que, embora não haja nenhum atributo crossOrigin, e a configuração crossOrigin=use-credentials reportará um erro de domínio cruzado por padrão, eles são de natureza diferente.
compatibilidade crossOriginTodos os navegadores IE11+ (IE Edge), Safari, Chrome e Firefox suportam IE9 e IE10 reportarão um SecurityError, conforme mostrado na captura de tela abaixo:
4. Por que o atributo crossOrigin pode resolver o problema de recursos entre domínios?crossOrigin=anonymous Em vez de informar o outro servidor, você não precisa trazer nenhuma informação não anônima. Por exemplo, cookies, portanto, o navegador atual é definitivamente seguro.
É como se você quisesse ir na casa de alguém pegar uma peça de roupa crossOrigin=anonymous é diferente de dizer para a outra pessoa que eu só quero a roupa e nada mais. Se você não contar, a outra parte poderá colocar um dispositivo de escuta ou algo em suas roupas, o que não será seguro e o navegador irá bloqueá-lo.
5. O que devo fazer se o navegador IE10 não suportar crossOrigin?Quando solicitamos imagens, não usamos diretamente new Image(), mas usamos ajax e o método URL.createObjectURL() para salvar o país.
O código é o seguinte:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); Você pode usar o canvas para fazer o que quiser com img // ... code ... // Lembre-se de liberar a memória após usar a imagem URL.revokeObjectURL(url }); = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
Este método não é adequado apenas para o navegador IE10, mas também é compatível com todos os navegadores que originalmente suportavam crossOrigin.
Requer apenas mais uma solicitação ajax, o que é bom!
De acordo com a prática, no navegador IE, se a imagem solicitada for muito grande, alguns milhares de pixels, a imagem não será carregada, acho que excede o limite de tamanho do blob.
6. ConclusãoAprendi um pouco de experiência no trabalho recentemente e espero que possa ajudar amigos que enfrentam problemas semelhantes. Também espero que todos apoiem a Rede VeVb Wulin.