如何在Ionic 5中不使用FileTransfer从URL下载文件

11

我目前正在开发Ionic应用程序,卡在了文件下载部分。我看到许多帖子说FileTransfer cordova库现在已被淘汰,建议使用XHR请求。

尽管我看到很多帖子说该库已经被淘汰,但我找不到任何示例代码(用于从URL下载文件)。

请问有没有好的方法可以从URL下载文件而不使用FileTransfer插件?

6个回答

11

从另一个服务器下载文件可能会导致令人讨厌的 CORS 错误,这通常超出我们的控制范围。最安全的方法是绕过 Webview 并本地下载文件。您可以使用 Native HTTP 插件。

Ionic 4 或以上版本中的使用示例如下:

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);
        })
     }
  }
}

1
这在本地设备上可以完美运行,但在浏览器中有没有解决方法? - Nischaya Sharma
1
这对我没用。没有错误,只是什么也没有发生。 - Yevhenii Bahmutskyi
@YevheniiBahmutskyi,你在哪里测试?这段代码是针对本地设备的,你不能使用浏览器进行测试。你尝试过在调试模式下在设备上测试并在终端/命令窗口上打印控制台日志吗? - Arup Bhattacharya
@ArupBhattacharya 谢谢您的解决方案。我在iOS设备上使用了您的函数,但是我遇到了这个问题:“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 ... 下载文件时出现错误。” - Réda Youssoufi

1

这是我在React中使用的解决方案,下载MP4文件并保存到缓存或文档中,使用Capacitor的Filesystem进行操作。

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
您可以简单地使用HttpClient类(@angular/common/http)如下所示:
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});
});

您需要导入以下内容:

import { HttpClient } from '@angular/common/http';
import { File } from '@ionic-native/file/ngx';

1
你可以使用window打开URL。但这将会在浏览器中打开并下载文件。虽然不太美观,但这样做能完成任务。

your.page.ts:

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

your.html:

<a href="javascript:void(0)" (click)="download(yourUrl)">Your file name</>

0
为了能够通过ionic-native File下载和查看文件,我不得不在Xcode中添加额外的设置:

confing.xml

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

info.plist

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

下载路径应为File.documentsDirectory


-1
您可以按照以下步骤实现: 步骤1:编写一个从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( () => { });
}


步骤2:使用下载函数将其转换为适当的 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
 }
);


步骤三:使用以下插件https://github.com/apache/cordova-plugin-file将Blob数据保存在设备上。


当我向服务器发送获取文件的请求时,我遇到了CORS错误。我需要在后端管理CORS吗? - Ioan Moldovan
好的,顺便问一下,你能分享完整的源代码作为参考吗?并且我认为我们可以在GET请求中使用reponsetype: blob - Ioan Moldovan
这是我的导入语句,它抛出了错误import { Observable } from 'rxjs';。请展示Observable的导入语句,因为这里显示无法在Observable上使用.catch。 - Nischaya Sharma
这段代码无效且写得很糟糕。 - Yevhenii Bahmutskyi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接