Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS #1544

Open
icezeko opened this issue May 26, 2018 · 22 comments
Open

CORS #1544

icezeko opened this issue May 26, 2018 · 22 comments

Comments

@icezeko
Copy link

icezeko commented May 26, 2018

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.

@CrandellWS
Copy link

CrandellWS commented Nov 4, 2018

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...

@pritambios
Copy link

pritambios commented Mar 29, 2019

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.

@Rostislav-Poleshko
Copy link

Thank you @Pritam1994

@sougatabose07
Copy link

Hi,

I have added the following options -

allowTaint : false,
useCORS: true

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

@gaoming13
Copy link

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/

@rup9823
Copy link

rup9823 commented Dec 29, 2020

I am using version 1.0.0-rc.0 and just adding @CrandellWS's solution didn't work
The part of html2canvas.js file where the correction has to be made is like this

if (!supportsDataImages || useCORS){
    img.crossOrigin = 'anonymous';
} 
    img.onerror = reject;
    img.src = src;

Adding src alone won't work, the code has to be like this

if (!supportsDataImages || useCORS){
    img.crossOrigin = 'anonymous';
    img.src = src +'?v='+new Date().getTime();
} 
else{
    img.src = src;
}
    img.onerror = reject;

@SalahAdDin
Copy link

It seems it is not fixed yet.

@yulisartika
Copy link

been stuck for days and finally found the solution from here:
https://developpaper.com/question/img-add-crossorigin-anonymous-and-the-picture-will-not-be-displayed/

in addition, I added:

useCORS: true

and on the img tag: <img imageUrl + '?time=' + new Date().valueOf() crossorigin='anonymous'>

hope this helps

@SalahAdDin
Copy link

@yulisartika Well, when i put crossorigin='anonymou' the brower simply can't fetch the image, hence, it can't show them.

@CrandellWS
Copy link

@SalahAdDin as @yulisartika said

and on the img tag: <img imageUrl + '?time=' + new Date().valueOf() crossorigin='anonymous'>

setting the image url to have an unique parameter is key

@arohablue
Copy link

been stuck for days and finally found the solution from here: https://developpaper.com/question/img-add-crossorigin-anonymous-and-the-picture-will-not-be-displayed/

in addition, I added:

useCORS: true

and on the img tag: <img imageUrl + '?time=' + new Date().valueOf() crossorigin='anonymous'>

hope this helps

@yulisartika Well, when i put crossorigin='anonymou' the brower simply can't fetch the image, hence, it can't show them.

Adding crossOrigin="" did it for me.

@cezarcozta
Copy link

@arohablue for me did not =´(

@SalahAdDin
Copy link

@arohablue for me did not =´(

We had to make a proxy server.

@arohablue
Copy link

arohablue commented Apr 3, 2022

@arohablue for me did not =´(

For me the image is stored on WAS so I also added a cors filter there and used the below to fetch it.
<img src={bucketURL+ '?time=' + new Date().valueOf()} crossOrigin=""/>

@IntelligaiaVivek
Copy link

IntelligaiaVivek commented May 20, 2022

As i need to get screenshot for iframe from other page but its in same domain but then also getting this error:- Failed to execute 'open' on 'Document': Can only call open() on same-origin documents Getting this error on html2canvas any help appreciated

@SalahAdDin
Copy link

As i need to get screenshot for iframe from other page but its in same domain but then also getting this error:- Failed to execute 'open' on 'Document': Can only call open() on same-origin documents Getting this error on html2canvas any help appreciated

Proxy server I would say.

@yanghoxom
Copy link

Has anyone had the same situation as me?
some images can be downloaded, but some give cors error even though they are in the same bucket
s3 bucket setup cors AllowOriginls: ["*"]
I use the option useCORS: true

jhihruei added a commit to jhihruei/html2canvas that referenced this issue Aug 16, 2022
jhihruei added a commit to jhihruei/html2canvas that referenced this issue Aug 16, 2022
jhihruei added a commit to jhihruei/lodestar-app that referenced this issue Aug 16, 2022
@RSchneider94
Copy link

for people still having the issue, for me what worked was a mix of some replies here.. I have:

<img imageUrl + '?time=' + new Date().valueOf() crossorigin="">

plus { allowTaint: true, useCORS: true } in html2canvas and then it worked! Image is hosted on S3.

@xrzhuang
Copy link

@RSchneider94 i wish it wa that easy for some reason when I have crossorigin="" or anonymous my images don't even render at all.

@memsenpai I have the exact same issue as you my S3 bucket has AllowOrigin wildcard

@w4cernesto
Copy link

been stuck for days and finally found the solution from here: https://developpaper.com/question/img-add-crossorigin-anonymous-and-the-picture-will-not-be-displayed/
in addition, I added:
useCORS: true
and on the img tag: <img imageUrl + '?time=' + new Date().valueOf() crossorigin='anonymous'>
hope this helps

@yulisartika Well, when i put crossorigin='anonymou' the brower simply can't fetch the image, hence, it can't show them.

Adding crossOrigin="" did it for me.

For me was the response!!

@yanghoxom
Copy link

@xrzhuang I must use a server as a proxy to solve that issue :(

@zakpucci
Copy link

zakpucci commented Apr 3, 2024

For anyone who may have run into this seemingly simple issue. As long your application can make cross origin requests fine and your only issue is html2canvas not being able to reach those URLs, you can convert your visible images to data URLs prior to the canvas printing to bypass the need for html2canvas to fetch them cross origin.

This is the only way I was able to get around this without proxy or reworking CORS in my functions or server.

--
Loop over your node for img tags, set the src to await toDataURL(img.src)

const toDataURL = async (src) => {
  let blob = await fetch(src).then((r) => r.blob());
  let d = await new Promise((resolve) => {
    let reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
  return d;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests