2

In Angular 5, I want to download an image from localhost (server). I already have the image name with the path as: http://localhost/projectName/uploads/3/1535352341_download.png Now I want to download by clicking on a button.

In the HTML view in Angular, I wrote the following code:

<button (click)="downloadImage(car.carItem.carTitle)" type="button" class="btn btn-sm btn-info btn-action" tooltip="Download Image" placement="left" container="body"><i class="fa fa-download" aria-hidden="true"></i></button>

In the .ts file, I do the following but it opens the image in the same tab:

downloadImage(imagePath){
  window.location = imagePath;
}

I have already gone through the post Angular 4 direct download images but unable to find any solution. So please don't mark it as duplicate.

6 Answers6

5

Since your image is on a remote server, you can't download it simply as you would with your own ressources for security reasons.

This what a simple downloadUrl function looks like, It will ask the browser to download any given url:

    function downloadUrl(url: string, fileName: string) {
      const a: any = document.createElement('a');
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.style = 'display: none';
      a.click();
      a.remove();
    };

Since we can't download remote ressources, we will have to built it client-side. We will fetch the resource and create its own url. Then we will finally be able to download it using our downloadUrl function.

    constructor(
      private http: HttpClient,
    ) { }

-------
    this.http.get(urlImage, { responseType: 'blob' }).subscribe(val => {
      console.log(val);
      const url = URL.createObjectURL(val);
      downloadUrl(url, 'image.png');
      URL.revokeObjectURL(url);
    });
raaaay
  • 496
  • 7
  • 14
Ploppy
  • 14,810
  • 6
  • 41
  • 58
2
<a href=" http://localhost/projectName/uploads/3/1535352341_download.png" class="btn clss"
                  target="_self" download>Download</a>
Anoop Babu
  • 178
  • 12
  • 12
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Narendra Jadhav Aug 27 '18 at 13:40
  • 2
    The solution doesn't even work, it just opens the image on the browser in the same tab. – Benneee_ Apr 15 '21 at 07:08
1
  constructor(private rs: RequestService,
      private http: Http,
      private sanitizer: DomSanitizer) {
  }

  getImage(imageUrl: string) {
      return this.http
                 .get(imageUrl, {responseType: ResponseContentType.Blob})
                 .map((res) => {
                     return new Blob([res.blob()], {type: res.headers.get('Content-Type')});
                 });
  }

  downloadImage(downloadLink) {
      this.orderService
          .getImage(downloadLink)
          .subscribe(
              (res) => {
                  const a = document.createElement('a');
                  a.href = URL.createObjectURL(res);
                  a.download = 'comprobante';
                  document.body.appendChild(a);
                  a.click();
              });
  }
peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76
1

Thanks @Ploppy for leading me in the right direction,

Here is my solution, with using fetch (TypeScript) and bypassing cors

const getExternalImageFromURL = (requesturl: string): Promise<Blob> => {
    const proxyurl = "https://cors-anywhere.herokuapp.com/";

    return fetch(proxyurl + requesturl).then((res) => {
        return res.blob();
    });
};
Ianc22
  • 119
  • 10
0

Whenever you have requirement to do CORS in your application then at server side there must be some mechanism to allow ONLY specified cross site request, so below snippet is for NodeJs

let middle_ware = (req, res, next) => next();
...
return function (req, res, next) {
    const allowed_Origins = ['http://any_url.com'];
    const origin = req.headers.origin;
    if (allowed_Origins.includes(origin)) {
      res.header('Access-Control-Allow-Origin', origin);
    }
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    res.header({
      HttpOnly: true,
      Secure: true,
      SameSite: 'None',
    });
    middle_ware(req, res, next);
  };

and if you were using PHP, I hope in PHP this might help you Cross-Origin Request Headers(CORS) with PHP headers Thank you!

Vinod
  • 1,234
  • 3
  • 21
  • 37
0

I used SaveAs to download image from unsplash .

Step1. Installation

npm i angular-file-saver

Step2. Import this into your component import { saveAs } from 'file-saver/FileSaver';

Step3. Call a function with image url as argument

download(url){
    this.http.get(url,{ responseType: 'blob' }).subscribe(
      (d:any)=>{
        console.log("image url data",d);
        saveAs(d, "image.jpg");
    
      },
      (err:any)=>{
        console.log("error",err)
      }
    )
  
  }