Généralement, les équipes auront un nom de domaine spécial pour placer les ressources statiques, telles que gtimg.com de Tencent et bdimg.com de Baidu, ou de nombreuses équipes utilisent les services Tencent Cloud ou Alibaba Cloud ;
Les noms de domaine des pages principales sont souvent différents. Lorsqu'il est nécessaire d'effectuer des opérations getImageData() ou toDataURL() sur des images canevas, des problèmes inter-domaines surviennent et il existe plusieurs niveaux de problèmes inter-domaines.
Tout d'abord, dans un premier temps, le serveur d'images doit configurer les informations Access-Control-Allow-Origin, par exemple :
Par exemple, PHP ajoute des informations d'en-tête de réponse et le caractère générique * indique que n'importe quel nom de domaine est autorisé :
en-tête (Access-Control-Allow-Origin: *);
Ou spécifiez un nom de domaine :
en-tête (Access-Control-Allow-Origin : www.zhangxinxu.com) ;
À l'heure actuelle, le navigateur Chrome n'affichera plus de messages d'erreur liés à Access-Control-Allow-Origin, mais il y aura d'autres messages d'erreur inter-domaines.
2. Image de toile problème inter-domaines d'origine croisée getImageDataPour les images inter-domaines, tant qu'elles peuvent être affichées normalement sur la page Web, elles peuvent être dessinées à l'aide de l'API drawImage() de Canvas. Mais si vous souhaitez aller plus loin et obtenir les informations complètes sur les pixels de l’image via la méthode getImageData(), vous ferez probablement une erreur.
Par exemple, utilisez le code suivant pour obtenir les informations de votre propre image d'avatar sur github :
var canvas = document.createElement('canvas');var contexte = canvas.getContext('2d');var img = new Image();img.onload = function () { context.drawImage(this, 0, 0) ; contexte.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Le résultat est l'erreur suivante affichée sous le navigateur Chrome :
DOMException non interceptée : échec de l'exécution de "getImageData" sur "CanvasRenderingContext2D" : le canevas a été entaché de données d'origine croisée.
L'erreur du navigateur Firefox est :
SecurityError : l'opération n'est pas sécurisée.
Si la méthode canvas.toDataURL() est utilisée, elle rapportera :
Échec de l'exécution de 'toDataURL' sur 'HTMLCanvasElement' : le canevas contaminé ne peut pas être exporté
Les raisons sont en fait les mêmes, causées par plusieurs domaines.
Alors, y a-t-il un moyen de résoudre ce problème ?
Vous pouvez essayer l'attribut crossOrigin.
3. L'attribut HTML crossOrigin résout le problème des ressources entre domainesEn HTML5, certains éléments fournissent des attributs qui prennent en charge CORS (Cross-Origin Resource Sharing) (partage de ressources entre origines croisées). Ces éléments incluent <img>, <video>, <script>, etc., et le nom de l'attribut fourni est le. Attribut crossOrigin.
Par conséquent, le problème inter-domaines ci-dessus peut être traité comme ceci :
var canvas = document.createElement('canvas');var contexte = canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (this, 0, 0); contexte.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Ajoutez simplement un img.crossOrigin = '' Bien que le code JS définisse ici une chaîne vide, la valeur réelle de l'attribut qui fonctionne est anonyme.
crossOrigin peut avoir les deux valeurs suivantes :
Mots-clés | Définition |
---|---|
anonyme | Les demandes de ressources d’origine croisée pour les éléments ne nécessitent pas la définition de l’indicateur d’informations d’identification. |
utiliser les informations d'identification | Les demandes de ressources inter-domaines pour les éléments nécessitent que l'indicateur d'informations d'identification soit défini, ce qui signifie que des informations d'identification sont requises pour la demande. |
Parmi eux, tant que la valeur de l'attribut crossOrigin n'est pas use-credentials, tout sera analysé comme anonyme, y compris les chaînes vides, y compris les caractères comme « abc ».
Par exemple:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // Le résultat est 'anonyme'
Une autre chose à noter est que bien qu'il n'y ait pas d'attribut crossOrigin et que la définition de crossOrigin=use-credentials signalera par défaut une erreur inter-domaines, ils sont de nature différente et il existe une grande différence entre les deux.
compatibilité crossOriginLes navigateurs IE11+ (IE Edge), Safari, Chrome et Firefox le prennent tous en charge. IE9 et IE10 signaleront une SecurityError, comme indiqué dans la capture d'écran ci-dessous :
4. Pourquoi l'attribut crossOrigin peut-il résoudre le problème des ressources inter-domaines ?crossOrigin=anonymous Au lieu d'en informer l'autre serveur, vous n'avez pas besoin d'apporter d'informations non anonymes. Par exemple, les cookies, le navigateur actuel est donc définitivement sûr.
Tout comme vous voulez aller chez quelqu'un d'autre pour récupérer un vêtement, crossOrigin=anonymous est différent de dire à l'autre personne que je veux seulement les vêtements et rien d'autre. Si vous ne leur dites pas, l'autre partie peut mettre un appareil d'écoute ou quelque chose dans ses vêtements, ce qui sera dangereux et le navigateur le bloquera.
5. Que dois-je faire si le navigateur IE10 ne prend pas en charge crossOrigin ?Lorsque nous demandons des images, nous n'utilisons pas directement new Image(), mais utilisons ajax et la méthode URL.createObjectURL() pour enregistrer le pays.
Le code est le suivant :
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); Vous pouvez utiliser canvas pour faire ce que vous voulez avec img // ... code ... // N'oubliez pas de libérer la mémoire après avoir utilisé l'image URL.revokeObjectURL(url }; = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
Cette méthode convient non seulement au navigateur IE10, mais est également prise en charge par tous les navigateurs prenant initialement en charge crossOrigin.
Cela ne nécessite qu’une requête ajax supplémentaire, ce qui est très bien !
Selon la pratique, sous le navigateur IE, si l'image demandée est trop grande, quelques milliers de pixels, l'image ne pourra pas se charger, je suppose qu'elle dépasse la limite de taille du blob.
6. ConclusionJ'ai récemment appris une petite expérience au travail, j'espère que cela pourra aider des amis qui rencontrent des problèmes similaires. J'espère également que tout le monde soutiendra le réseau VeVb Wulin.