skip to Main Content

What I want to achieve:

When the user clicks a button, the image should be saved to Photos.

What’s the current behaviour:

On click, the user is sent to a new page that only that image exists.

<a href={imageUrl} target="_blank">button</a>

On click, the user is asked if they want to download the image. Upon accepting it, the image is saved in OneDrive instead of their Photos, which causes them not able to find it.

export const downloadFile = (url: string, filename: string) => {
    fetch(url)
    .then(response => {
        response.blob().then(blob => {
            let url = window.URL.createObjectURL(blob);
            let a = document.createElement('a');
            a.href = url;
            a.download = filename;
            a.click();
            a.remove();
        });
    });
}

Is there a better way to let the user download the image directly to their Photos instead of either of the two actions above?

UPDATE:

Tried with the mime-type and content-disposition, still sent to File instead of Photos.

enter image description here

And when I open the link on iOS, it pop up a dialog like this:

enter image description here

When I click "View", it will open a page with the image shown.

When I click "Download", it will download to my iCloud Drive directly without letting me choose to save it in my Photos.

3

Answers


  1. You can use a library called File-saver. Read more about it on this page: https://www.npmjs.com/package/file-saver. It has a function saveAs() which you can use like this.

    FileSaver.saveAs("https://httpbin.org/image", "image.jpg");
    

    Hope this will help you.

    Login or Signup to reply.
  2. If your back-end server defines image resource as Content-Disposition (rfc here https://datatracker.ietf.org/doc/html/rfc6266), you can just make browser to trigger image download with window.location.assign("[image-url]").
    Note that you have to response Content-Type header correctly based on image’s format(.jpg, .png or others) on your back-end server implementation.

    Login or Signup to reply.
  3. if you only want to download an image, maybe you can try this code

    function onDownloadImage(src) {
      const img = new Image();
      img.crossOrigin = "anonymous";
      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);
        // for create tag anchor
        const a = document.createElement("a");
        a.download = `image-download`;
        a.href = canvas.toDataURL("image/png");
        a.click();
      };
    }
    

    after that you can call this function inside your component. for example:

    return (
     <a href="#" onClick={() => onDownloadImage("url your image")}>Download Here ...</a>
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search