11

I'm currently developing Ionic app now and stuck at file download part. I saw many posts that FileTransfer cordova library is now deprecated in favor of XHR request.

Even though I saw many posts that the library is deprecated, I can't find any sample code (for downloading file from URL).

Could anyone please suggest me good way to download file from url without using FileTransfer plugin?

Snow
  • 3,820
  • 3
  • 13
  • 39
Ioan Moldovan
  • 2,272
  • 2
  • 29
  • 54

6 Answers6

11

Downloading files from another server may cause annoying CORS error which is mostly beyond our control. The safest way is to bypass the Webview and download the file natively. You may use Native HTTP plugin

Use in Ionic 4 or above will look like:

import { Component } from '@angular/core';
import { HTTP } from '@ionic-native/http/ngx';
import { File } from '@ionic-native/file/ngx';
        
@Component({
   selector: 'app-home',
   templateUrl: './you-file.html',
   styleUrls: ['./your-file.scss'],
})

export class HomePage {
    constructor(private nativeHTTP: HTTP, private file: File) {}
        
     private downloadFileAndStore() {
        //
        const filePath = this.file.dataDirectory + fileName; 
                         // for iOS use this.file.documentsDirectory
        
        this.nativeHTTP.downloadFile('your-url', {}, {}, filePath).then(response => {
           // prints 200
           console.log('success block...', response);
        }).catch(err => {
            // prints 403
            console.log('error block ... ', err.status);
            // prints Permission denied
            console.log('error block ... ', err.error);
        })
     }
  }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 1
    This works like a charm for native devices, but is there any workaround in this for browser. – Nischaya Sharma Aug 15 '21 at 06:06
  • 1
    this doesn't work for me. No errors, just nothing is happening – Yevhenii Bahmutskyi Aug 16 '21 at 09:38
  • @YevheniiBahmutskyi where are you testing? the code is for native devices and you can not test this using your browser. Have you tried testing on your device in debug mode and printing console logs on the terminal/command window? – Arup Bhattacharya Sep 16 '21 at 12:02
  • @ArupBhattacharya thank you for solution. I use your function on ios device and I have this issue : " 2021-09-17 11:18:41.526015+0100 F[1617:318799] error block ... 403 2021-09-17 11:18:41.526434+0100 F[1617:318799] error block ... There was an error downloading the file" – Réda Youssoufi Oct 11 '21 at 13:37
1

You can just open the url with window. But this will open a browser and download the file there. It will do the trick although it is not pretty:

your.page.ts:

function download(url){
  window.open(url, "_blank");
}

your.html:

<a href="javascript:void(0)" (click)="download(yourUrl)">Your file name</>
Pouria Moosavi
  • 662
  • 7
  • 22
1

This is the solution I used for react, downloading files MP4 and save in the cache or documents, Filesystem is for capacitor.

const bob = await fetch(url).then((x) => x.blob());
       const base64 = await convertBlobToBase64(bob);

    const resultSaveFile = await Filesystem.writeFile({
        data: base64,
        path: 'video-edit.mp4',
        directory: directory || Directory.Cache,
        recursive: true,
      });
1

You can use simply HttpClient class (@angular/common/http) as follow:

const downloadPath = (
   this.platform.is('android')
) ? this.file.externalDataDirectory : this.file.documentsDirectory;


let vm = this;

/** HttpClient - @angular/common/http */
this.http.get(
   uri, 
   {
      responseType: 'blob', 
      headers: {
         'Authorization': 'Bearer ' + yourTokenIfYouNeed,
      }
   }
).subscribe((fileBlob: Blob) => {
   /** File - @ionic-native/file/ngx */
   vm.file.writeFile(downloadPath, "YourFileName.pdf", fileBlob, {replace: true});
});

Imports you will need:

import { HttpClient } from '@angular/common/http';
import { File } from '@ionic-native/file/ngx';
tomloprod
  • 7,472
  • 6
  • 48
  • 66
0

To be able to download and see files via ionic-native File I had to add additional settings inside Xcode:

confing.xml

<preference name="iosPersistentFileLocation" value="Library" />

info.plist

<key>UIFileSharingEnabled</key> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key> <true/>

Download path should be File.documentsDirectory

Ihor
  • 571
  • 6
  • 10
-1

You can Achieve this in the following steps :

Step 1: A download function to download from URL

downloadFile(path: string, body: Object = {}): Observable<any> {
  let headers = {} // add authentication headers and other headers as per your requirement
  return this.http.post/get( 
    `${path}`, body, { headers: headers, withCredentials: true }
  )
  .catch((err) =>console.log(err))
  .map((res:Response) => res)
  .finally( () => { });
}


Step 2: Use the download function to convert it into an appropriate Blob.

this.downloadFile(`url`, postData).subscribe(
 res => {
   let options = { type: ‘filetype’ };
   let filename = ‘filename.type’;
   Util.createAndDownloadBlobFile(res._body, options, filename);
 },
 err => {
   // show the error
 }
);


Step 3: Save the Blob Data on Device using following plugin https://github.com/apache/cordova-plugin-file