Html2canvas: CORS

Created on 26 May 2018  路  5Comments  路  Source: niklasvh/html2canvas

i'm trying to take a shot of a google recaptcha challenge loaded by iframe from another iframe, already used allowTaint and useCORS, and all i get is a error.

0ms html2canvas: html2canvas 1.0.0-alpha.12
10ms html2canvas: DOMException: Failed to execute 'open' on 'Document': Can only call open() on same-origin documents.
DOMException: Failed to execute 'open' on 'Document': Can only call open() on same-origin documents.

Most helpful comment

Thank you @CrandellWS
I have solved it using your solution this way.

const image = "https://s3-us-west-2.amazonaws.com/github.png?1551296103"
const timestamp = new Date().getTime();
const imageWithTimestamp = image.includes('?') ? `${image}&v=${timestamp}` : `${image}?v=${timestamp}`;

render() {
  return (
    <div>
      <h1>Hello world</h1>
      <img
         src={imageWithTimestamp}
         alt={imageName}
         crossOrigin="anonymous"
      />
    </div>
  );
}

Please make sure that you image is returning CORS enable headers. Otherwise you have to add CORS policy to your s3 bucket.

All 5 comments

I fixed some cors issues I was having with the combination of Google Chrome, AWS S3, and multiple origins.

I found this stackoverflow thread:
https://stackoverflow.com/questions/26352083/chrome-cors-cache-requesting-same-file-from-two-different-origins

Which links to this bug report:
https://bugs.chromium.org/p/chromium/issues/detail?id=260239

Anyhow as workaround solution you can try this modified version of html2canvas:
https://gist.github.com/CrandellWS/6bc2078aced496004d7a045e6360f19b

use the options:

allowTaint : false,
useCORS: true

Hope that helps.

FYI, this will add the current time stamp to cors image urls to sidestep a cache issue I was having on Chrome...
https://gist.github.com/CrandellWS/6bc2078aced496004d7a045e6360f19b#file-html2canvas-js-L6838

Which means it will effect performance by re-downloading those images...

Thank you @CrandellWS
I have solved it using your solution this way.

const image = "https://s3-us-west-2.amazonaws.com/github.png?1551296103"
const timestamp = new Date().getTime();
const imageWithTimestamp = image.includes('?') ? `${image}&v=${timestamp}` : `${image}?v=${timestamp}`;

render() {
  return (
    <div>
      <h1>Hello world</h1>
      <img
         src={imageWithTimestamp}
         alt={imageName}
         crossOrigin="anonymous"
      />
    </div>
  );
}

Please make sure that you image is returning CORS enable headers. Otherwise you have to add CORS policy to your s3 bucket.

Thank you @pritam1994

Hi,

I have added the following options -

allowTaint : false,
useCORS: true

Bit it is not showing captcha. Instead a blank box.

Without modifying html2canvas, here is an idea:
First use canvas to convert cross-domain pictures into Base64 encoding, and then give it to html2canvas for processing

// 1.First get the Base64 encoding of cross-domain pictures through canvas
const img = new Image();
img.onload = () => {
  const c = this.$refs.crossImg;
  const ctx = c.getContext('2d');
  ctx.drawImage(img, 0, 0, c.width, c.height);
  this.crossImgBase64 = c.toDataURL('image/png');

  // 2.Draw
  Html2canvas(this.$refs.html, {
    // useCORS: true,
  }).then((canvas) => {
    this.pngBase64 = canvas.toDataURL('image/png');
    this.isShowPng = true;
  });
};
img.crossOrigin = 'anonymous';
img.src = 'https://secure.gravatar.com/avatar/03af4ed2fa8526e9f37c847cc4083141';

Here a example

https://vue-html2canvas-safari-bug.stackblitz.io/

Was this page helpful?
0 / 5 - 0 ratings