bubkoo / html-to-image

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

Image is displayed in browser, but doesn't come through with download (Safari) #348

Open Yehuda-Edelstein opened 1 year ago

Yehuda-Edelstein commented 1 year ago

Expected Behavior

I'm trying to download html including an img tag using safari, but the source doesn't show up, just an empty div.

Current Behavior

I have a preview box:

function Preview() {
          const mobileRef = useRef(null);
          const download = () => {
            setIsLoading(true);
            toPng(mobileRef.current, {})
              .then((dataUrl) => {
                const link = document.createElement("a");
                link.download = "youtube.png";
                link.href = dataUrl;
                link.click();
                setIsLoading(false);
              })
              .catch((err) => {
                console.log(err);
              });
          };

        return (
                <div>
                  <div ref={mobileRef}>
                    <img src={img} alt="" />
                  </div>
                  <button onClick={download}>DOWNLOAD</button>
                </div>
        )
}

When I download the image I get all the html besides the picture; instead just an empty div. where the image should be. All other parts of the html convert and download as a PNG, so I'm confused as to why the only issue is converting the img, especially when the img is being displayed in the browser. I'm wondering if this is a react issue, or just an issue with downloading images of an img.

Possible Solution

I'm not sure what's causing this, maybe it's an issue with my set up or css, but it doesn't really make sense to me. Someone mentioned in the comments that it may be an issue with CORS; I checked the network tab on safari when I hit download and there are a few things that come up:

Screenshot 2022-12-26 at 12 40 03 AM

The bottom is the png file (my static file) that is displayed in the browser but not when I download the html. Here it is displayed as a png, headers read 200, status okay.

Next up is an svg of the entire downloaded html. Inside the network tab, the svg file shows everything even the static png that doesn't show up in the downloaded html-to-image. Headers also read 200.

Next is an xhr, looks the same as the first png. Also 200.

The top 3 are all 304 not modified.

I'm pretty new to coding so all of this doesn't really make a lot of sense to me.

Steps To Reproduce

Best way to reproduce this is to just use the code example I gave and replace the src with any photo you have locally or online. I tried downloading with local photos and with google photos/gifs online and both ways come back with an empty div. I think it's important to state again that the images are displaying in the safari browser, they just don't get converted from html to PNG.

Your Environment

Since this is only happening to me in safari, I can't help but think it's not an issue with my code. Of course it could be -- I am setting my img with a react setState and having the src={require('')} but again, since the img displays in the browser, I can't help but think it's just a bug. Would love to help more, just not really sure what's causing the issue.

vivcat[bot] commented 1 year ago

👋 @Yehuda-Edelstein

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

pabloiea1995 commented 1 year ago

Hello Yehuda! We faced the same issue, and it turned out to be a cors error with our image server. checkout the network Tab to see if that's the case. If it is, we solved it through the server configuration.

Hope it helps!

Yehuda-Edelstein commented 1 year ago

how do i test that out tho, if the error only happens through safari, or other mobile os? Is there a way to just add a fix assuming the issue is with cors?

Yehuda-Edelstein commented 1 year ago

WebSocket network error: The operation couldn’t be completed. (OSStatus error -9847.) I get this error in network/messages when I run the code over browserstack to recreate apple os

Yehuda-Edelstein commented 1 year ago

Hello Yehuda! We faced the same issue, and it turned out to be a cors error with our image server. checkout the network Tab to see if that's the case. If it is, we solved it through the server configuration.

Hope it helps!

Also what do you mean through server configuration exactly.

pabloiea1995 commented 1 year ago

I am not sure what that error means exactly as I tested it in Chrome browser and it shows a CORS error. Maybe you should checkout if that error is related to CORS. When I talk about server configuration I mean proxy headers. We realized it was our server problem because internet images (for example from google images) loaded correctly. You could do the same test to discard this problem

labaran1 commented 1 year ago

Facing the same issue here. I'm getting a cors error. @pabloiea1995 I currently don't get your fix.

Yehuda-Edelstein commented 1 year ago

You get the error on mobile only or also on desktop?

On Mon, Dec 19, 2022 at 9:49 AM labaran1 @.***> wrote:

Facing the same issue here. I'm getting a cors error. @pabloiea1995 https://github.com/pabloiea1995 I currently don't get your fix.

— Reply to this email directly, view it on GitHub https://github.com/bubkoo/html-to-image/issues/348#issuecomment-1357780728, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWAMRKY56IBS2DPQBIJTM5DWOBYXPANCNFSM6AAAAAATAKQYQM . You are receiving this because you were mentioned.Message ID: @.***>

labaran1 commented 1 year ago

Desktop. Using Ubuntu 22.04.1 LTS chrome. Mobile Safari
@pabloiea1995

Yehuda-Edelstein commented 1 year ago

how did you see what type of errors it was on mobile safari? Like I can't figure out how to inspect or see errors with mobile safari

labaran1 commented 1 year ago

Okay, my bad. I mean the issue is also on safari mobile. but, if you have a mac, you can use the web inspector. Go to settings on your phone, then safari, then toggle Web Inspector.

how did you see what type of errors it was on mobile safari? Like I can't figure out how to inspect or see errors with mobile safari

Yehuda-Edelstein commented 1 year ago

So I think the issue is with safari, not just on mobile. Just use safari on my mac and it downloads all the html besides the image, however the image is previewed in the browser. I checked and there are no errors. The network tab shows a 200, what's even weirder is that when I look at the data when I download the html as png, in the preview tab it shows the image I upload, but doesn't come through when I download the html.

labaran1 commented 1 year ago

So I think the issue is with safari, not just on mobile. Just use safari on my mac and it downloads all the html besides the image, however the image is previewed in the browser. I checked and there are no errors. The network tab shows a 200, what's even weirder is that when I look at the data when I download the html as png, in the preview tab it shows the image I upload, but doesn't come through when I download the html.

before the cors error, I experienced this same issue with chrome.

Yehuda-Edelstein commented 1 year ago

Have you seen the same error using safari? Also what was ur fix?

On Mon, Dec 19, 2022 at 12:41 PM labaran1 @.***> wrote:

So I think the issue is with safari, not just on mobile. Just use safari on my mac and it downloads all the html besides the image, however the image is previewed in the browser. I checked and there are no errors. The network tab shows a 200, what's even weirder is that when I look at the data when I download the html as png, in the preview tab it shows the image I upload, but doesn't come through when I download the html.

before the cors error, I experienced this same issue with chrome.

— Reply to this email directly, view it on GitHub https://github.com/bubkoo/html-to-image/issues/348#issuecomment-1358015317, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWAMRK2OTO24IJPAJEKPL6TWOCM5BANCNFSM6AAAAAATAKQYQM . You are receiving this because you were mentioned.Message ID: @.***>

labaran1 commented 1 year ago

I've not fixed it yet. It's a ticket I'm working on.

Have you seen the same error using safari? Also what was ur fix? On Mon, Dec 19, 2022 at 12:41 PM labaran1 @.> wrote: So I think the issue is with safari, not just on mobile. Just use safari on my mac and it downloads all the html besides the image, however the image is previewed in the browser. I checked and there are no errors. The network tab shows a 200, what's even weirder is that when I look at the data when I download the html as png, in the preview tab it shows the image I upload, but doesn't come through when I download the html. before the cors error, I experienced this same issue with chrome. — Reply to this email directly, view it on GitHub <#348 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWAMRK2OTO24IJPAJEKPL6TWOCM5BANCNFSM6AAAAAATAKQYQM . You are receiving this because you were mentioned.Message ID: @.>

Yehuda-Edelstein commented 1 year ago

After going over the issue more, it's definitely limited to safari.

dhruvilxcode commented 1 year ago

I am facing a similar issue, I tested the library with Chrome on iOS, and The behaviour is the same as safari on iOS. The issue is only on iPhone. as I tested with Android, and Desktop, I got good results.

If anyone has a fix for it, I would greatly appreciate it. 👍🏻

Yehuda-Edelstein commented 1 year ago

I have the same issue with desktop safari, as well as with safari on iphone.

On Sat, Dec 31, 2022 at 1:20 AM Dhruvil @.***> wrote:

I am facing a similar issue, I tested the library with Chrome on iOS, and The behaviour is the same as safari on iOS. The issue is only on iPhone. as I tested with Android, and Desktop, I got good results.

If anyone has a fix for it, I would greatly appreciate it. 👍🏻

— Reply to this email directly, view it on GitHub https://github.com/bubkoo/html-to-image/issues/348#issuecomment-1368172259, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWAMRK32SUWTYBVNPCEMAILWP7GC7ANCNFSM6AAAAAATAKQYQM . You are receiving this because you were mentioned.Message ID: @.***>

s-kris commented 1 year ago

Same issue. The image is lost after downloading.

Bug appears in safari on iPhone and desktop.

dhruvilxcode commented 1 year ago

Used html2canvas for now, and rendered the dynamic content on the page until the image is created, once the image is created, removed the dynamic content from a page. Through this process, I was able to get good results on iPhone (Safari and Chrome) and Android. Although you have to sacrifice on performance. Now, a 1080x1920 Pixel hi-res image takes anywhere between 2-7 seconds.

minusmo commented 1 year ago

@dhruvilxcode hey! Can you please tell me how you overcame this issue with ios safari? I also have same issue and tried other solutions but nothing worked.

dhruvilxcode commented 1 year ago

@minusmo I replaced this library with the html2canvas. what I did is rendered the content on the page by inserting the dynamically generated content then I called the method to convert data to base64 image. once image is generated I removed the content from page that I added previously programmatically.

The implementation really depends on the usecase. and I found that if content is available on the page (not dynamic content) then these libraries works well.

qq15725 commented 1 year ago

The problem seems to be a bug of Safari requiring multiple delayed calls to drawImage 😓

https://github.com/bubkoo/html-to-image/issues/361#issuecomment-1413526381

Yehuda-Edelstein commented 1 year ago

The problem seems to be a bug of Safari requiring multiple delayed calls to drawImage 😓

#361 (comment)

How can I implement that instead of this package? Yours is typscript, can't figure out how to replace this function with that.

Yehuda-Edelstein commented 1 year ago

Hello Yehuda! We faced the same issue, and it turned out to be a cors error with our image server. checkout the network Tab to see if that's the case. If it is, we solved it through the server configuration.

Hope it helps!

your issue was also exclusively on Safari?

wenlittleoil commented 1 year ago

I have the same issue with iphone mobile, the android mobile and pc browser web are all normal.

juliabelle1 commented 1 year ago

Hi! I also had the same issue with safari when I used html-to-image https://www.npmjs.com/package/html-to-image. I solved it with another library html2canvas https://www.npmjs.com/package/html2canvas. I have converted the html to image in this library and rendered them in @react-pdf/renderer.

Here is my code: const [image, setImage]=useState(null)

function to convert image

const handleCreateImage = async () => {
    const element = document.getElementById('element-id'),
      canvas = await html2canvas(element),
      data = canvas.toDataURL("image/jpg", 1);
    setImage(data);
  };

this data i convert to image <div id='element-id'>some data</div>

And here I render my image in pdf.

<PDFViewer style={viewerStyle}>
        <Document>
          <Page size="A4" style={pageStyle}>
            <View style={styles.section}>
              <Image src={`${image}`} />
            </View>
          </Page>
        </Document>
      </PDFViewer>

Hope it will help.

mattscotty commented 7 months ago

The problem seems to be a bug of Safari requiring multiple delayed calls to drawImage 😓 #361 (comment)

How can I implement that instead of this package? Yours is typscript, can't figure out how to replace this function with that.

Did you figure this out? I'm in the same boat.

Ironically I'm trying to migrate from html-to-canvas because of issues with nested images inside SVGs. html-to-image solves my issues and seems more accurate, but isn't working on safari :(

s-kris commented 7 months ago

I switched to this lib: https://github.com/qq15725/modern-screenshot Works great.

mattscotty commented 7 months ago

I switched to this lib: https://github.com/qq15725/modern-screenshot Works great.

Thanks @s-kris you've saved the day with that, much appreciated. This is the third or fourth type of plugin I've tried and this one seems to be the best so far. Just one issue I can see with pseudo element font icons not working, but it's a minor issue; https://github.com/qq15725/modern-screenshot/issues/68

s-kris commented 6 months ago

Oh! I didn't know the font issue.

But glad it helped you.

MohamedAlosaili commented 6 months ago

Hello Yehuda! We faced the same issue, and it turned out to be a cors error with our image server. checkout the network Tab to see if that's the case. If it is, we solved it through the server configuration.

Hope it helps!

Thanks your solution worked with me. Another way might help is to download the image before add it to the dom that being converted into an image.

hungdev commented 1 month ago

I switched to this lib: https://github.com/qq15725/modern-screenshot Works great.

greate, thank for sharing solution