2

I want to simulate Save Image As when the user clicks on an image.

I read this and this thread but I couldn't find the answer.

I'm using CRA and the image is not on my server. Is there a way where I can achieve this?

Here is a Sandbox:

https://codesandbox.io/s/save-image-as-react-pm3ts?file=/src/App.js


 <a
    href="https://img.mipon.org/wp-content/uploads/2019/12/14094031/logo-cover-website.png"
    download
      >
        <img
          download
          alt="Mipon"
          style={{ width: "300px" }}
          onClick={() => console.log("should trigger save image as")}
          src="https://img.mipon.org/wp-content/uploads/2019/12/14094031/logo-cover-website.png"
        />
</a>

Alfrex92
  • 6,278
  • 9
  • 31
  • 51

1 Answers1

3

The download attribute will not work as intended since Blink engine will block cross-origin <a download>. Checkout Deprecations and removals in Chrome 65.

To avoid what is essentially a user-mediated cross-origin information leakage, Blink will now ignore the presence of the download attribute on anchor elements with cross origin attributes. Note that this applies to HTMLAnchorElement.download as well as to the element itself.

You may try to draw the image to a canvas element and download its dataURL. But this approach will work only if the requested domain has an Access-Control-Allow-Origin headers that allow shared requests. Images without CORS approval will taint the canvas and you will encounter error Tainted canvases may not be exported download image when you try to use methods like toDataURL(). In that case, you can host the image with services like Cloudinary and the download with canvas approach will work.

Here is a function to download an image using canvas, you may use it in a onclick event handler:

function downloadImage(src) {
  const img = new Image();
  img.crossOrigin = 'anonymous';  // This tells the browser to request cross-origin access when trying to download the image data.
  // ref: https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#Implementing_the_save_feature
  img.src = src;
  img.onload = () => {
    // create Canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
    // create a tag
    const a = document.createElement('a');
    a.download = 'download.png';
    a.href = canvas.toDataURL('image/png');
    a.click();
  };
}

Edit save-image-as-react

hangindev.com
  • 4,573
  • 12
  • 28