Tengo una página con varias portadas de libros y un botón para descargarlos todos.
Las portadas de los libros están en formato de cadena y son una URL de Google Books. Estoy poblando así:
<section ref="capture" id="my-node"> <figure v-for="book in books" :key="book.id"> <img :src="book.thumbnail" :alt="`Book ${book.title}`" /> </figure> <button type="button" @click="download">html2canvas</button> </section>Para descargar las portadas de los libros estoy llamando a la siguiente función:
download() { html2canvas(this.$refs["capture"], { allowTaint: true }) .then((canvas) => { let link = document.createElement("a"); link.download = "Livrero.png"; link.href = canvas.toDataURL("image/png"); link.click(); }) }, Books es un objeto que contiene una propiedad de thumbnail con valores como este: https://books.google.com/books/content?id=_i6bDeoCQzsC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
Lo que me confunde más es que si estuviera usando valores similares a este: https://images-na.ssl-images-amazon.com/images/I/41xShlnTZTL._SX218_BO1,204,203,200_QL40_FMwebp_.jpg todo estaría funcionando, pero lamentablemente el proyecto no lo permite por el momento.
Anteriormente estaba usando la propiedad useCORS: true en html2canvas , sin embargo, devolvía un error de política de CORS. Entonces, cuando lo eliminé, dejé de tener este error y comencé a recibir el siguiente error:
DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.Se sugirió que usara http://html2canvas.hertzen.com/proxy/ para tener éxito en la misión, pero debido a que estoy usando Vue.js, no sé cómo aplicarlo.
Este es un problema con la política de contenido del navegador. No hay una solución sencilla.
El navegador no le permitirá usar contenido (imágenes) de diferentes orígenes que no lo permitan explícitamente.
Con useCORS: true , se espera que el servidor (con el recurso remoto) responda con los encabezados access-control-allow-origin apropiados. Tu enlace de Amazon sí, por eso funciona.
Con allowTaint: true , acepta la imagen, pero luego se niega a permitirle hacer algo con la imagen del lienzo resultante, ya que ahora se considera contaminada .
Dado que no puede hacer que el servidor de terceros envíe encabezados CORS apropiados, deberá ejecutar su propio proxy CORS.
Para ejecutar html2canvas-proxy mencionado en la documentación oficial , debe instalarlo
npm install html2canvas-proxy --savehacer un archivo JavaScript de inicio
var proxy = require('html2canvas-proxy'); var express = require('express'); const port = 8000; var app = express(); app.use('/', proxy()); app.listen(port, () => { console.log(`html2canvas-proxy listening on port ${port}`) }) y luego use la opción de proxy en html2canvas
html2canvas(this.$refs["capture"], { proxy: "http://localhost:8000", }) .then((canvas) => { // ... })Pero para la producción, este proxy simple tampoco es bueno, ya que permite que cualquiera lo use como un proxy CORS y es posible que no desee un servidor separado, si aún no está ejecutando un servidor Express Node.js.