La spécification HTML introduit un attribut crossorigin
pour les images. Cet attribut, combiné avec l'en-tête CORS (Cross-Origin Resource Sharing) approprié, permet aux images définies via l'élément <img>
et qui proviennent d'emplacements étrangers d'être utilisées dans le canevas de la même manière que si elles avaient été chargées depuis l'origine de la page actuelle.
Voir les configurations des attributs CORS pour plus de détails sur l'utilisation de l'attribut crossorigin
.
Qu'est-ce qu'un canevas « corrompu » ?
Bien qu'il soit possible d'utiliser des images non-approuvées par le CORS dans votre canevas, le faire corrompt le canevas. Une fois qu'un canevas a été corrompu, on ne peut plus retirer de données du canevas. On ne peut donc plus, par exemple, utiliser les méthodes liées au canevas comme toBlob()
, toDataURL()
, ou getImageData()
. Les utiliser produira une erreur de sécurité.
C'est mesure de protection qui empêchent les utilisateurs d'accéder à des données privées en utilisant des images provenant de sites distants sans que cela ait été autorisé.
Exemple : stocker une image venant d'un site extérieur
Dans le cas où on dispose d'un serveur stockant des images avec l'en-tête Access-Control-Allow-Origin
appropriée, on pourra sauvegarder ces images dans localStorage
comme si elles étaient servies depuis son propre domaine.
Côté serveur, on pourra utiliser ce modèle (basé sur les configurations Apache modèles) pour renvoyer la réponse appropriée avec le bon en-tête :
<IfModule mod_setenvif.c> <IfModule mod_headers.c> <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$"> SetEnvIf Origin ":" IS_CORS Header set Access-Control-Allow-Origin "*" env=IS_CORS </FilesMatch> </IfModule> </IfModule>
Au niveau du client, on pourra utiliser le code JavaScript suivant :
var img = new Image; var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); var src = "https://www.exemple.com/image"; // l'URL de l'image img.crossOrigin = "Anonymous"; img.onload = function() { canvas.width = img.width; canvas.height = img.height; ctx.drawImage( img, 0, 0 ); localStorage.setItem( "donnéesSauvegardées", canvas.toDataURL("image/png") ); } img.src = src; // on s'assure de charger les événements également pour les images mises en cache if ( img.complete || img.complete === undefined ) { img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; img.src = src; }
Compatibilité des navigateurs
Fonctionnalité | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Support simple | 13 | 8 | Pas de support | Pas de support | Nightly build |
Fonctionnalité | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Support simple | ? | ? | ? | ? | ? |