web-dev-qa-db-fra.com

Toile teintée de données d'origine croisée

Je charge un fichier JPEG depuis un site tiers, auquel je peux faire confiance. J'essaie de getImageData() mais le navigateur (Chrome 23.0) se plaint de ce qui suit:

Unable to get image data from canvas because the canvas has been tainted by
cross-Origin data.

Il y a des questions similaires sur SO, mais ils utilisent un fichier local et j'utilise un média tiers. Mon script s'exécute sur un serveur partagé et je ne possède pas le serveur distant.

J'ai essayé img.crossOrigin = 'Anonymous' ou img.crossOrigin = '' (voir cet article sur le blog de Chromium sur CORS ), mais cela n'a pas aidé. Avez-vous une idée de la manière dont je peux getImageData sur un canevas avec des données d'origine croisée? Merci!

14
clwen

Vous ne pouvez pas réinitialiser le drapeau crossOrigin une fois qu’il est corrompu, mais si vous savez au préalable quelle est l’image, vous pouvez la convertir en une URL de données, voir Dessin d’une image depuis une URL de données vers une zone de dessin

Mais non, vous ne pouvez et ne devriez pas utiliser getImageData () à partir de sources externes qui ne prennent pas en charge CORS.

10
Paul Kaplan

Bien que la question soit très ancienne, le problème persiste et il n’ya que peu d’internet pour le résoudre. Je suis venu avec une solution que je veux partager:

Vous pouvez utiliser l'image (ou la vidéo) sans l'attribut crossorigin défini au préalable et vérifier si vous pouvez obtenir une demande HEAD via la même ressource via AJAX. Si cela échoue, vous ne pouvez pas utiliser la ressource. s'il réussit, vous pouvez ajouter l'attribut et redéfinir la source de l'image/vidéo avec un horodatage attaché qui le rechargera.

Cette solution de contournement vous permet d'afficher votre ressource à l'utilisateur et de simplement masquer certaines fonctions si CORS n'est pas pris en charge.

HTML:

<img id="testImage" src="path/to/image.png?_t=1234">

JavaScript:

var target = $("#testImage")[0];
    currentSrcUrl = target.src.split("_t=").join("_t=1"); // add a leading 1 to the ts
$.ajax({
    url: currentSrcUrl,
    type:'HEAD',
    withCredentials: true
})
.done(function() {
    // things worked out, we can add the CORS attribute and reset the source
    target.crossOrigin = "anonymous";
    target.src = currentSrcUrl;
    console.warn("Download enabled - CORS Headers present or not required");
    /* show make-image-out-of-canvas-functions here */
})
.fail(function() {
    console.warn("Download disabled - CORS Headers missing");
    /* ... or hide make-image-out-of-canvas-functions here */
});

Testé et fonctionnant dans IE10 + 11 et dans les versions actuelles de Chrome 31, FF25, Safari 6 (Bureau) . Dans IE10 et FF, vous pourriez rencontrer un problème si et seulement si vous essayez d'accéder à des fichiers http à partir d'un script https. Je ne sais pas encore de solution de rechange pour cela.

MISE À JOUR Jan 2014:

Les en-têtes CORS requis pour cela devraient être les suivants (syntaxe de configuration Apache):

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "referer, range, accept-encoding, x-requested-with"

l'en-tête x est requis pour la demande ajax uniquement. Il n'est pas utilisé par tous mais par la plupart des navigateurs, autant que je sache.

9
Jörn Berkefeld

Il convient également de noter que le CORS s'appliquera si vous travaillez localement, que la ressource se trouve dans le même répertoire que le fichier index.html avec lequel vous travaillez. Pour moi, cela signifie que les problèmes de CORS ont disparu lorsque je les ai téléchargés sur mon serveur, car ils ont un domaine.

5
Kristopher Ives

Vous pouvez utiliser base64 de l'image sur la toile, Lors de la conversion en base64, vous pouvez utiliser une URL de proxy ( https://cors-anywhere.herokuapp.com/ ) devant le chemin de votre image -Origin issue

vérifier tous les détails ici

_ { https://stackoverflow.com/a/44199382/5172571 } _

var getDataUri = function (targetUrl, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        var reader = new FileReader();
        reader.onloadend = function () {
            callback(reader.result);
        };
        reader.readAsDataURL(xhr.response);
    };
    var proxyUrl = 'https://cors-anywhere.herokuapp.com/';
    xhr.open('GET', proxyUrl + targetUrl);
    xhr.responseType = 'blob';
    xhr.send();
};
getDataUri(path, function (base64) {
    // base64 availlable here
})
1
Manish Mittal