How to make Html2Canvas work with external images?

I’ve been trying to use Html2Canvas to export some book images, but I’m getting the following error:

Access to image at 'https://books.google.com/books/content?id=1JkccukKkQcC&printsec=frontcover&img=1&zoom=1&source=gbs_api'
from origin 'http://localhost:8080' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

I get such an error for every image. Here’s a mock of what I’m doing:

download () {
  window.html2canvas(this.$refs['capture'], {
    allowTaint: true,
    proxy: "https://books.google.com/",
    useCORS: true,
  })
    .then(canvas => document.body.appendChild(canvas))
    .catch(err => console.error("Error:", err));
}

I also made a JSFidle with everything working (except the image of course).

https://jsfiddle.net/arnonrdp/bkfa8opt/17/

I also read in the documentation that to make it work it would be necessary to implement html2canvas-proxy-nodejs, but I have no idea how to do that in Vue.

Has anyone gone through this problem?

You wouldn’t be doing that in Vue, you’d be doing that on a server running Node. This is how you achieve a proxy for resources blocked by CORS.

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.

Resource: Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Browser, being the key word. Browsers must adhere to CORS policies, servers on the other hand don’t have this concept so a proxy can be used to make the request. So the request path essentially becomes, browser => node proxy => books.google.com => node proxy => browser

1 Like

So it’s harder than I thought. I figured it would just be a Proxy implementation.
In my case, my application doesn’t have a backend running Node (unless Vercel is doing it under the hood).
Can you think of a solution?

You could use a cloud service such as Heroku or AWS. A quick google brought up this article for a Heroku proxy: How to create a proxy server on Heroku - DEV Community

1 Like

You should maybe look at this: Allowing cross-origin use of images and canvas - HTML: HyperText Markup Language | MDN

1 Like

I don’t have much experience with CORS and I don’t know how to apply this in a project with Vue:

<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    <FilesMatch "\.(avifs?|bmp|cur|gif|ico|jpe?g|jxl|a?png|svgz?|webp)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS
    </FilesMatch>
  </IfModule>
</IfModule>

But I’m studying how to solve this. If you have an idea, it might help me a lot.