Heim  >  Artikel  >  Web-Frontend  >  Lösungen für Kompatibilitätsprobleme mit canvas.toDataURL unter IE11

Lösungen für Kompatibilitätsprobleme mit canvas.toDataURL unter IE11

php中世界最好的语言
php中世界最好的语言Original
2018-04-14 14:12:506606Durchsuche

Dieses Mal werde ich Ihnen Ideen zur Lösung des Kompatibilitätsproblems bei der Verwendung von canvas.toDataURL in IE11 vorstellen Tatsächlicher Kampf Werfen wir einen Blick auf den Fall.

Problem gefunden Kürzlich wurde im Projekt die toDataURL-Methode von Canvas verwendet, um die Base64-Formatdaten des

Bildes

zum Hochladen in den Hintergrund abzurufen. Da ich zuvor auf die Gefahr gestoßen bin, dass die Leinwand durch domänenübergreifende Bilder kontaminiert wird und keine Daten abgerufen werden können, habe ich von Anfang an geschickt den Wert des Attributs crossOrigin hinzugefügt. Der Code lautet ungefähr wie folgt:

Ich dachte, es sei narrensicher und im Chrome-Browser lief es sehr reibungslos. Unter IE11 ist jedoch ein unerklärlicher Sicherheitsfehler aufgetreten:
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
context.fillStyle = "black";
context.fillRect(0, 0, canvas.width, canvas.height);
const imageElement = document.createElement("img");
imageElement.crossOrigin = "Anonymous";
imageElement.onload = () => {
 context.drawImage(
 imageElement,
 params.left,
 params.top,
 canvas.width,
 canvas.height,
 0,
 0,
 canvas.width,
 canvas.height
 );
 const dataUrl = canvas.toDataURL("image/jpeg", 1);
}
imageElement.src = 'xxx';

Lösungen für Kompatibilitätsprobleme mit canvas.toDataURL unter IE11 Es gibt keine spezifische Fehlermeldung, nur die Zeile zum Ausführen von toDataURL befindet sich über der Eingabeaufforderung, was wirklich verwirrend ist.

Versuchen Sie es Ich habe es zum ersten Mal gegoogelt und festgestellt, dass viele Leute auf dieses Problem gestoßen sind, aber keine wirksame Lösung gefunden haben. Einige Leute schlugen vor, Fabric.js zu verwenden, aber nachdem sie es sich angesehen hatten, hielten sie es für zu mühsam. Auf caniuse wird auch deutlich darauf hingewiesen, dass diese Methode im IE11 Probleme hat.

Es schien ein Fehler im IE zu sein, also habe ich mir eine Möglichkeit überlegt, das Land zu retten: Es gibt nicht nur eine Möglichkeit, die Base64-Daten des Bildes zu erhalten. Da die toDataURL-Methode nicht gut unterstützt wird, verwenden Sie eine andere Methode:

    Konvertieren Sie zunächst Canvas in Blob
  • Verwenden Sie dann FileReader, um
  • in Form von dataUrl zu lesen Der Code lautet ungefähr wie folgt:

Dies nützt jedoch nichts....
const reader = new FileReader();
reader.readAsDataURL(canvas.msToBlob());
reader.onloadend = () => {
 const base64data = reader.result;
};

Diesmal war es die msToBlob-Methode, einen SecurityError zu melden. ICH:? ? ?

Lösung Es scheint, dass es sich tatsächlich um einen Sicherheitsgrund handelt. Der einzige Sicherheitsgrund sind domänenübergreifende Bilder. Ich dachte, dass die Sicherheitsrichtlinien im IE möglicherweise strenger sind und die Daten auch dann nicht gelesen werden dürfen, wenn

festgelegt ist. Da es sich um eine domänenübergreifende Methode handelt, entfernen Sie das Kreuz -Domänenfaktor:

crossOrigin = "Anonymous"

    Verwenden Sie Ajax, um die Binärdaten des Bildes anzufordern
  • Konvertieren Sie Binärdaten in das Base64-Format
  • Legen Sie die erhaltenen Base64-Daten als Quelle des Bildelements fest und zeichnen Sie sie auf die Leinwand
  • Rufen Sie normalerweise toDataURL
  • auf
Der Code lautet ungefähr wie folgt:

Habe es ausprobiert und das Ziel erfolgreich erreicht.
// 之前的代码
// ...
// 最后一行 imageElement.src = 'xxx' 替换:
getDataUrlBySrc('xxx').then(b64 => (imageElement.src = b64));
function getDataUrlBySrc(src: string) {
 return new Promise<string>((resolve, reject) => {
 if (Cache.localGet("isIE")) {
  const xmlHTTP = new XMLHttpRequest();
  xmlHTTP.open("GET", src, true);
  // 以 ArrayBuffer 的形式返回数据
  xmlHTTP.responseType = "arraybuffer";
  xmlHTTP.onload = function(e) {
  
  // 1. 将返回的数据存储在一个 8 位无符号整数值的类型化数组里面
  const arr = new Uint8Array(xmlHTTP.response);
  
  // 2. 转为 charCode 字符串
  const raw = Array.prototype.map
   .call(arr, charCode => String.fromCharCode(charCode))
   .join("");
   
  // 3. 将二进制字符串转为 base64 编码的字符串
  const b64 = btoa(raw);
  
  const dataURL = "data:image/jpeg;base64," + b64;
  resolve(dataURL);
  };
  xmlHTTP.onerror = function(err) {
  reject(err);
  };
  xmlHTTP.send();
 } else {
  resolve(src);
 }
 });
}</string>

Später habe ich die Informationen überprüft und festgestellt, dass weder toDataURL noch toBlob erfolgreich ausgeführt werden, wenn die Leinwand kontaminiert ist.

Mängel Obwohl diese Methode das Ziel erreichen kann, geht sie zu Lasten der Leistung. Sie müssen nicht nur die Bilddaten zuerst anfordern, auch die Konvertierung der Datenkodierung ist recht zeitaufwändig. Kleine Bilder sind in Ordnung, aber wenn das Bild relativ groß ist, beispielsweise mehr als 3 Megapixel, kann der gesamte Vorgang ein oder zwei Minuten dauern, was inakzeptabel ist.

Wird toDataUrl von Canvas das Bild komprimieren? Wenn Sie die drawImage-Methode von Canvas verwenden, um ein Bildobjekt auf die Leinwand zu zeichnen, erhöht sich die Bildgröße erheblich und kann nur im PNG-Format gespeichert werden.

Konvertieren Sie die Leinwand mit toDataUrl in Base64. Auch wenn EncoderOptions auf 1 gesetzt ist, wird das Bild stark verkleinert, ist aber immer noch größer als das Originalbild. Wenn EncoderOptions den Standardwert 0,92 verwendet, ähnelt die endgültige Bildgröße der ursprünglichen.

Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln Artikel auf der chinesischen PHP-Website!

Empfohlene Lektüre:

So verwenden Sie die Angular4-Eingabe und -Ausgabe

So implementieren Sie das dynamische Kaskadenladen der Easyui-Dropdown-Box (mit Code)

Das obige ist der detaillierte Inhalt vonLösungen für Kompatibilitätsprobleme mit canvas.toDataURL unter IE11. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn