bubkoo / html-to-image

✂️ Generates an image from a DOM node using HTML5 canvas and SVG.
MIT License
5.63k stars 523 forks source link

image CORS problem #40

Closed soulcactus closed 3 years ago

soulcactus commented 4 years ago

image

This is a problem.

image

So I added this option, but it didn't work. How can I fix it?

Please comment me. Thank you.

duongtn811 commented 4 years ago

hi, you can fix by adding

fetch(url, { method: 'GET', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', }, })

in getBlobFromURL.js

soulcactus commented 4 years ago

thank you for your help! :)

dpk-kakkar commented 4 years ago

while adding google charts - I am getting this error. Any solution?

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.gstatic.com/charts/47/css/table/table.css. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

twickstrom commented 4 years ago

@bubkoo are you open to adding a production flag or debug flag to this package if I submit a pull request? If not, I understand, but this is not production ready, as is, if it will throw errors in the console for third party link tags that I have no control over.

vivcat[bot] commented 3 years ago

Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not-stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

Thanks for being a part of the Antv community! 💪💯

Arslan0510 commented 3 years ago

Please help me with this I tried htmlToImage.toPng(node, { useCorsEverywhereProxy: true }) but didn't work 1111

andreastepel commented 3 years ago

Has anyone found a valid solution for this issue? I am facing it as well and none of the above solutions worked for me.

EDIT: I have found out that the issue only occurs with AWS Cloudfront not if I use the direct source of AWS S3. Anyone has an idea why?

Arslan0510 commented 3 years ago

No. Not yet

On Wed, Nov 18, 2020 at 11:49 PM Andreas Tepel notifications@github.com wrote:

Has anyone found a valid solution for this issue?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bubkoo/html-to-image/issues/40#issuecomment-729882277, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMBDY56YUHYFJOJYDKNPPALSQQJLVANCNFSM4KJP5HNQ .

-- Regards,

Arslan Ali +92 333 514 2005

vivcat[bot] commented 3 years ago

Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not-stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

Thanks for being a part of the Antv community! 💪💯

soulcactus commented 3 years ago

guys, try this

https://soulcactus.netlify.app/development/canvas-image-cors/

vivcat[bot] commented 3 years ago

Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not-stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

Thanks for being a part of the Antv community! 💪💯

marcosem commented 3 years ago

Got same error here, the image is stored on Amazon AWS S3.

marcosem commented 3 years ago

guys, try this

https://soulcactus.netlify.app/development/canvas-image-cors/

Tried and it worked for me when added crossOrigin="anonymous" to the img tag.

Thank you!

simplecommerce commented 3 years ago

guys, try this https://soulcactus.netlify.app/development/canvas-image-cors/

Tried and it worked for me when added crossOrigin="anonymous" to the img tag.

Thank you!

@marcosem Thank you for your hint, it helped me solve an issue with remote css also from google fonts, I added crossorigin="anonymous" and it no longer gives me errors and the fonts are loaded without issues!

fpstidston commented 3 years ago

I have this problem. Images are rendered as missing becuase the CORS policy. Adding crossorigin="anonymous" to the images did not fix it

simplecommerce commented 3 years ago

@fpstidston what is your img url, can you show us your example?

fpstidston commented 3 years ago

The team logos appear in the DOM but not in the output. The API owner allows all CORS

image image
simplecommerce commented 3 years ago

@fpstidston I have tried a few things but don't know how to fix it, from my tests if I look at the request headers, when I don't put the crossorigin="anonymous", the browser sends mode="no-cors" which loads fine, but if I put crossorigin="anonymous" or "use-credentials" it sends mode="cors" to the server and causes the error.

Not sure if this means that the SERVER doesn't have cors enabled and causes the issue maybe.

fpstidston commented 3 years ago

If by server you are referring the api image host I have asked them and they have said they allow CORS and I can verify that they load within by browser when the developer mode allow cors setting is off

simplecommerce commented 3 years ago

Here is what I mean @fpstidston

I tried both of these <img src="https://media.api-sports.io/football/teams/41.png" /> (without crossorigin) which shows the first image (no-cors)

and then

<img src="https://media.api-sports.io/football/teams/41.png" crossorigin="anonymous" /> (with crossorigin) which shows the second image (cors), which fails to load the image at all on my browser.

image

That is why I am suspecting the API server might not have cors enabled at all, or if someone else is more familiar with this, can explain the issue.

vivcat[bot] commented 3 years ago

Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not-stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

Thanks for being a part of the Antv community! 💪💯

vivcat[bot] commented 3 years ago

Hey again! It’s been 60 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to comment on this issue or create a new one if you need anything else. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Thanks again for being part of the Antv community! 💪💯

Allaoua9 commented 3 years ago

Having the same problem with S3, any update with this issue ?

vagish8962 commented 3 years ago

Any luck, how to load cors images?

andregueva18 commented 3 years ago

Hi, any solution? :(

ggofron commented 2 years ago

why is this issue closed? I'm having the same problems with S3

ggofron commented 2 years ago

ok, I see there is actually a solution mentioned above. Thanks @marcosem , adding crossorigin="anonymous" to img tag solved cors problems.

raphaelsasso commented 2 years ago

I had the same problem with s3 and workaround it with this post: https://serverfault.com/questions/856904/chrome-s3-cloudfront-no-access-control-allow-origin-header-on-initial-xhr-req/856948#856948

RichieRunner commented 2 years ago

📣

For anybody with S3 CORS issue, you can get around this by setting your image src to be a data URI base64 encoded string instead of an image source path

<img src="data:image/png?format=svg;base64,xxx" />

This will force/trick html-to-image into thinking that your image source is from the same origin as your app and prevent any CORS issue that comes from cross source/origin requests. For best performance, you can have your backend convert your S3 source images into a base64 encoded string before sending to your frontend for rendering.

SalahAdDin commented 2 years ago

https://soulcactus.netlify.app/development/canvas-image-cors/

Nice, but, how can we get a image from src and make it a base64 image?

Sovai commented 1 year ago

I still have this issue

AminRafaey commented 1 year ago

I was facing the same issue with the S3 bucket and the reason which I figured it out in my case was initially browser was requesting the image and cashing it, but while generating a screenshot using html-to-image package, It was again requesting an image but the browser was not allowing that if you already have an image in the cache then why are you requesting it again. So just to trick the browser I passed this parameter htmlToImage.toJpeg(containerRef, { cacheBust: true }) and it started working fine.

Robw94 commented 1 year ago

I am still having this issue, { cachebust: true } did not fix it. I am getting an Image from S3, breaks when doing

htmlToImage .toBlob(element, { canvasHeight: 1080, canvasWidth: 1920, skipAutoScale: true, cacheBust: true, })

With a CORS error, also added base64 to the S3 bucket link and same result

icleitoncosta commented 1 year ago

Here is a solution that I believe is definitive.

Go to your AWS S3 configuration. Select Bucket > Permissions Cross-Origin Resource Sharing (CORS) To edit

Enter something like this (set it up your way, with your URLs). I configured everything, also because they are public and simple files that I access there.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
argarner commented 1 year ago

For anyone else who hits this issue, beware there is a Chromium bug that prevents the CORS headers from being cached along with the image, so if the image is cached by the browser before being queried by htmlToImage it will throw a CORS error even when the header exists on the resource.

To resolve, you still need the Access-Control-Allow-Origin header to be set correctly on the b/e, but you also need to use the cacheBust: true option when using an htmlToImage method, so it bypasses the browser cache.

ManuelFernando commented 1 year ago

The issue come from S3 and cloudfront for who are using AWS. Then I suggest to follow the recommendation of @icleitoncosta to configurare S3 and check this url https://repost.aws/knowledge-center/no-access-control-allow-origin-error which indicate how to allow CORS headers pass from cloudfront to S3.

In my case I could resolve this issue and it's working fine to me 🎉

oriollpz commented 1 year ago

Any solutions?

baba43 commented 1 year ago

No, we are looking for the same problem.

Our problem here is that templates might contain images we do not have access to, so we cannot set any Cors headers.

If there is not at least a hack to get it working, I think we have to create a proxy server just for this reason.

Vesely commented 1 year ago

We are using S3 and add cacheBust: true to options resolved this issue.

Madjda commented 1 year ago

📣

For anybody with S3 CORS issue, you can get around this by setting your image src to be a data URI base64 encoded string instead of an image source path

<img src="data:image/png?format=svg;base64,xxx" />

This will force/trick html-to-image into thinking that your image source is from the same origin as your app and prevent any CORS issue that comes from cross source/origin requests. For best performance, you can have your backend convert your S3 source images into a base64 encoded string before sending to your frontend for rendering.

This works for me Thanks! I used this function to get the base64 from url

  const getBase64FromUrl = async (url) => {
    const imageData = await fetch(url);
    const blob = await imageData.blob();
    return new Promise((resolve) => {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = () => {
        const base64data = reader.result;
        resolve(base64data);
      }
    });
  }
JuanPionero commented 4 months ago

try it : htmlToImage.toBlob( (element, { pixelRatio: 1, fetchRequestInit: {mode:'no-cors'}}).then( ...

It was worked for me (used .toPng in stead of .toBlob).

risalfajar commented 4 months ago

If you're using Firebase or Google Cloud, this answer works.

raminr77 commented 3 months ago

I was facing the same issue with the S3 bucket and the reason which I figured it out in my case was initially browser was requesting the image and cashing it, but while generating a screenshot using html-to-image package, It was again requesting an image but the browser was not allowing that if you already have an image in the cache then why are you requesting it again. So just to trick the browser I passed this parameter htmlToImage.toJpeg(containerRef, { cacheBust: true }) and it started working fine.

It works for me! thanks a lot ❤️ I do it like this now: toJpeg(imageRef.current, { quality: 0.95, cacheBust: true })

wallace-yang commented 2 months ago

If you are using S3 and still getting a cross-origin error after adding {cacheBust: true}, then simply adjust S3 to allow cross-origin requests.

lfelipeserrano commented 1 month ago

I was facing the same issue with the S3 bucket and the reason which I figured it out in my case was initially browser was requesting the image and cashing it, but while generating a screenshot using html-to-image package, It was again requesting an image but the browser was not allowing that if you already have an image in the cache then why are you requesting it again. So just to trick the browser I passed this parameter htmlToImage.toJpeg(containerRef, { cacheBust: true }) and it started working fine.

This worked for me, using Google Cloud Storage for the image, I was using toPng in my case