Im Allgemeinen verfügen Teams über einen speziellen Domänennamen, um statische Ressourcen zu platzieren. Tencent ist beispielsweise gtimg.com, Baidu ist bdimg.com, oder viele Teams verwenden Tencent Cloud- oder Alibaba Cloud-Dienste.
Die Domänennamen der Hauptseiten sind häufig unterschiedlich. Wenn getImageData()- oder toDataURL()-Vorgänge für Leinwandbilder ausgeführt werden müssen, treten domänenübergreifende Probleme auf, und es gibt mehr als eine Ebene domänenübergreifender Probleme.
Im ersten Schritt muss der Bildserver zunächst die Informationen zu Access-Control-Allow-Origin konfigurieren, zum Beispiel:
PHP fügt beispielsweise Antwort-Header-Informationen hinzu und der Platzhalter * gibt an, dass jeder Domänenname zulässig ist:
header(Access-Control-Allow-Origin: *);
Oder geben Sie einen Domainnamen an:
header(Access-Control-Allow-Origin: www.zhangxinxu.com);
Zu diesem Zeitpunkt werden im Chrome-Browser keine Fehlermeldungen mehr im Zusammenhang mit „Access-Control-Allow-Origin“ angezeigt, es werden jedoch andere domänenübergreifende Fehlermeldungen angezeigt.
2. Canvas-Bild getImageData Cross-Origin-Cross-Domain-ProblemBei domänenübergreifenden Bildern können sie mit der drawImage()-API von Canvas gezeichnet werden, sofern sie normal auf der Webseite angezeigt werden können. Wenn Sie jedoch noch einen Schritt weiter gehen und die vollständigen Pixelinformationen des Bildes über die Methode getImageData() erhalten möchten, werden Sie wahrscheinlich einen Fehler machen.
Verwenden Sie beispielsweise den folgenden Code, um Ihre eigenen Avatar-Bildinformationen auf Github abzurufen:
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, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Das Ergebnis ist der folgende Fehler, der im Chrome-Browser angezeigt wird:
Nicht abgefangene DOMException: „getImageData“ konnte nicht auf „CanvasRenderingContext2D“ ausgeführt werden: Die Leinwand wurde durch ursprungsübergreifende Daten beeinträchtigt.
Der Firefox-Browserfehler ist:
SecurityError: Der Vorgang ist unsicher.
Wenn die Methode „canvas.toDataURL()“ verwendet wird, wird Folgendes gemeldet:
Fehler beim Ausführen von „toDataURL“ für „HTMLCanvasElement“: Befleckte Canvas-Elemente können möglicherweise nicht exportiert werden
Die Gründe sind tatsächlich dieselben und werden durch domänenübergreifende Probleme verursacht.
Gibt es also eine Möglichkeit, dieses Problem zu lösen?
Sie können das Attribut crossOrigin ausprobieren.
3. Das HTML-CrossOrigin-Attribut löst domänenübergreifende RessourcenproblemeIn HTML5 stellen einige Elemente Attribute bereit, die CORS (Cross-Origin Resource Sharing) (Cross-Origin Resource Sharing) unterstützen. Zu diesen Elementen gehören <img>, <video>, <script> usw., und der angegebene Attributname ist crossOrigin-Attribut.
Daher kann das obige domänenübergreifende Problem wie folgt behandelt werden:
var canvas = document.createElement('canvas');var context = canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (this, 0, 0); context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Fügen Sie einfach ein img.crossOrigin = '' hinzu. Obwohl der JS-Code hier eine leere Zeichenfolge festlegt, ist der tatsächliche Attributwert, der funktioniert, anonym.
crossOrigin kann die folgenden zwei Werte haben:
Schlüsselwörter | Definition |
---|---|
anonym | Für ursprungsübergreifende Ressourcenanforderungen für Elemente muss das Anmeldeinformationsflag nicht gesetzt sein. |
Anmeldeinformationen verwenden | Für domänenübergreifende Ressourcenanforderungen für Elemente muss das Flag „Anmeldeinformationen“ gesetzt sein, was bedeutet, dass für die Anforderung Anmeldeinformationen erforderlich sind. |
Unter diesen gilt: Solange der Attributwert von crossOrigin nicht use-credentials ist, wird alles als anonym analysiert, einschließlich leerer Zeichenfolgen, einschließlich Zeichen wie „abc“.
Zum Beispiel:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // Das Ergebnis ist 'anonymous';
Beachten Sie außerdem, dass es zwar kein crossOrigin-Attribut gibt und die Einstellung „crossOrigin=use-credentials“ standardmäßig einen domänenübergreifenden Fehler meldet, es jedoch einen großen Unterschied zwischen den beiden gibt.
CrossOrigin-KompatibilitätDie Browser IE11+ (IE Edge), Safari, Chrome und Firefox unterstützen dies alle. IE9 und IE10 melden einen SecurityError, wie im Screenshot unten gezeigt:
4. Warum kann das CrossOrigin-Attribut das Problem domänenübergreifender Ressourcen lösen?crossOrigin=anonymous Anstatt es dem anderen Server mitzuteilen, müssen Sie keine nicht anonymen Informationen mitbringen. Beispielsweise sind Cookies für den aktuellen Browser auf jeden Fall sicher.
Es ist so, als würde man zu jemandem nach Hause gehen, um ein Kleidungsstück abzuholen. Das ist etwas anderes, als der anderen Person zu sagen, dass ich nur die Kleidung will und sonst nichts. Wenn Sie es ihnen nicht sagen, kann die andere Partei ein Abhörgerät oder etwas Ähnliches in ihre Kleidung stecken, was unsicher ist und vom Browser blockiert wird.
5. Was soll ich tun, wenn der IE10-Browser crossOrigin nicht unterstützt?Wenn wir Bilder anfordern, verwenden wir nicht direkt new Image(), sondern verwenden Ajax und die Methode URL.createObjectURL(), um das Land zu speichern.
Der Code lautet wie folgt:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); img.onload = function () { // An dieser Stelle Sie können Canvas verwenden, um mit img // ... code ... // zu tun. Denken Sie daran, den Speicher freizugeben, nachdem Sie das Bild URL.revokeObjectURL(url) verwendet haben = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
Diese Methode ist nicht nur für den IE10-Browser in Ordnung, sondern wird auch von allen Browsern unterstützt, die ursprünglich crossOrigin unterstützt haben.
Es ist nur noch eine Ajax-Anfrage erforderlich, was in Ordnung ist!
Wenn das angeforderte Bild im IE-Browser zu groß ist (einige tausend Pixel), wird das Bild meiner Meinung nach nicht geladen, da es die Blob-Größenbeschränkung überschreitet.
6. FazitIch habe kürzlich ein paar Erfahrungen bei der Arbeit gesammelt und hoffe, dass es Freunden helfen kann, die auf ähnliche Probleme stoßen. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.