Maison > Article > interface Web > Solutions aux problèmes de compatibilité utilisant canvas.toDataURL sous IE11
Cette fois, je vais vous apporter des idées pour résoudre le problème de compatibilité lié à l'utilisation de canvas.toDataURL dans IE11. Quelles sont les précautions pour résoudre le problème de compatibilité lié à l'utilisation de canvas.toDataURL dans IE11. combat réel Jetons un coup d'œil au cas.
Problème trouvé
Récemment, la méthode toDataURL de canvas a été utilisée dans le projet pour obtenir les données au format base64 de l'image pour le téléchargement en arrière-plan. Depuis que j'ai déjà rencontré le piège d'un canevas contaminé par des images inter-domaines et incapable d'obtenir des données, j'ai intelligemment ajouté la valeur de l'attribut crossOrigin depuis le début. Le code est à peu près le suivant :
<.>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';Je pensais que c'était infaillible, et cela s'est très bien passé sur le navigateur Chrome, cependant, sur IE11, une SecurityError inexplicable s'est produite : Il n'y a pas de message d'erreur spécifique, seule la ligne d'exécution de toDataURL est localisée via l'invite, ce qui est vraiment déroutant.
Essayez
Je l'ai recherché sur Google pour la première fois et j'ai constaté que de nombreuses personnes ont rencontré ce problème, mais n'ont vu aucune solution efficace. Certaines personnes ont suggéré d'utiliser Fabric.js, mais après l'avoir examiné, elles ont pensé que c'était trop gênant. Sur caniuse, il est également clairement indiqué que cette méthode pose des problèmes sur IE11. Cela semblait être un bug sur IE, alors j'ai pensé à un moyen de sauver le pays : il n'y a pas qu'une seule façon d'obtenir les données base64 de l'image Puisque la méthode toDataURL n'est pas bien supportée, utilisez une autre méthode :
const reader = new FileReader(); reader.readAsDataURL(canvas.msToBlob()); reader.onloadend = () => { const base64data = reader.result; };
Cette fois, c'était au tour de la méthode msToBlob de signaler une SecurityError. JE:? ? ?
Solution Il semble que cela puisse vraiment être une raison de sécurité. La seule raison de sécurité concerne les images inter-domaines. Je pensais que la politique de sécurité sur IE pourrait être plus stricte, et même si
est défini, les données ne sont toujours pas autorisées à être lues, alors j'ai pensé à une autre idée puisqu'il s'agit de plusieurs domaines, puis supprimez la croix. -facteur de domaine :crossOrigin = "Anonymous"
Je l'ai essayé et j'ai atteint l'objectif avec succès.
// 之前的代码 // ... // 最后一行 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>
Plus tard, j'ai vérifié les informations et appris que si le canevas était contaminé, ni toDataURL ni toBlob ne seraient exécutés avec succès.
Défauts Bien que cette méthode puisse atteindre l’objectif, elle sacrifie les performances. Non seulement vous devez d'abord demander les données d'image, mais la conversion du codage des données prend également beaucoup de temps. Les petites images sont acceptables, mais si l'image est relativement grande, par exemple plus de 3M, l'ensemble du processus peut prendre jusqu'à une ou deux minutes, ce qui est inacceptable.
ToDataUrl du canevas compressera-t-il l'image ? Lorsque vous utilisez la méthode drawImage de Canvas pour dessiner un objet image sur le canevas, la taille de l'image augmentera considérablement et ne pourra être enregistrée qu'au format PNG.
Convertissez le canevas en base64 à l'aide de toDataUrl Même si encoderOptions est défini sur 1, l'image sera considérablement réduite, mais elle sera toujours plus grande que l'image d'origine. Si encoderOptions utilise la valeur par défaut de 0,92, la taille de l'image finale sera similaire à celle initiale
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres éléments connexes. articles sur le site PHP chinois !
Lecture recommandée :
Comment utiliser l'entrée et la sortie Angular4
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!