Tìm kiếm trang web

typescript - Làm thế nào để tôi có thể lưu một tệp đã tải xuống với Capacitor trong Ionic4 Angular?


Gần đây tôi đã phát hành ứng dụng Ionic 4 Angular của mình cả dưới dạng ứng dụng web và ứng dụng Android gốc.
Trong ứng dụng Android gốc, mọi thứ đều hoạt động tốt, ngoại trừ việc lưu một tệp đã tải xuống.

Để tải xuống và lưu một tệp, tôi luôn sử dụng gói npm file-saver như sau (đây là một dịch vụ chia sẻ mà tôi gọi mỗi khi phải tải xuống một thứ gì đó, từ PDF đến hình ảnh, v.v...):

import { saveAs } from 'file-saver';

// ...

saveGenericFile(api: string, fileinfos: any, idFile: string): any {
    let mediaType = 'application/pdf';
    let fileName = '';

    if (fileinfos != null) {
      mediaType = fileinfos.contentType;
      fileName = fileinfos.fileName;
    }

    const headers = this.base.commonHeader;
    const url = this.baseUrl + api + '?id=' + idFile;
    this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
      (response) => {
        // tslint:disable-next-line: prefer-const
        let blob = new Blob([response], { type: mediaType });
        saveAs(blob, fileName);
      }, e => {
        console.error(e);
        this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
      }, () => {
        /* do nothing */
      }
    );
  }

Như tôi đã nói ở trên, đoạn mã này hoạt động tốt, nhưng chỉ khi tôi phải lưu thứ gì đó từ phiên bản web.

Các ví dụ trực tuyến duy nhất mà tôi có thể tìm thấy đều liên quan đến Cordova và/hoặc các phiên bản trước/bị ngừng hỗ trợ.
Về Capacitor, tôi chỉ tìm thấy tài liệu này và từ đó tôi chỉ tìm thấy đoạn mã này:

import { Plugins, FilesystemDirectory, FilesystemEncoding } from '@capacitor/core';

const { Filesystem } = Plugins;

fileWrite() {
  try {
    Filesystem.writeFile({
      path: 'secrets/text.txt',
      data: "This is a test",
      directory: FilesystemDirectory.Documents,
      encoding: FilesystemEncoding.UTF8
    });
  } catch(e) {
    console.error('Unable to write file', e);
  }
}

Nhưng vấn đề là hàm của tôi ở trên trả về một blob và cái này chỉ chấp nhận một chuỗi cho dữ liệu.

Vậy, có tính năng tương đương với Capacitor-Native nào mà tôi có thể sử dụng để tải xuống (và lưu) tệp Blob cả khi chạy dưới dạng ứng dụng web lẫn khi chạy dưới dạng ứng dụng gốc trên Android không?

CẬP NHẬT

Tôi cũng đã thử những điều sau đây, nhưng nó không hoạt động:

saveGenericFile(api: string, fileinfos: any, gidFile: string): any {
    let mediaType = 'application/pdf';
    let fileName = '';

    if (fileinfos != null) {
      mediaType = fileinfos.contentType;
      fileName = fileinfos.fileName;
    }

    const headers = this.base.commonHeader;
    const url = this.baseUrl + api + '?id=' + gidFile;
    this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
      (response) => {
        if (!this.useCordovaDl) {
          // tslint:disable-next-line: prefer-const
          let blob = new Blob([response], { type: mediaType });
          saveAs(blob, fileName);
        } else {
          this.blobFileWrite(fileName, response);
        }
      }, e => {
        console.error(e);
        this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
      }, () => {
        /* do nothing */
      }
    );
  }

  blobFileWrite(filename: string, blobfile: Blob) {
    const reader = new FileReader();

    // This fires after the blob has been read/loaded.
    reader.addEventListener('loadend', (e: any) => {
      const text = e.srcElement.result;
      this.fileWrite(filename, text);
    });

    // Start reading the blob as text.
    reader.readAsText(blobfile);
  }

  fileWrite(filename: string, filedata: string) {
    try {
      Filesystem.writeFile({
        path: filename,
        data: filedata
        // ,
        // directory: FilesystemDirectory.Documents,
        // encoding: FilesystemEncoding.UTF8
      });
    } catch (e) {
      console.error('Unable to write file', e);
    }
  }

CẬP NHẬT #2

Có vẻ như vẫn còn một vấn đề mở trên GitHub về việc lưu trữ dữ liệu Blob với Capacitor. Trong khi đó, tôi sẽ tìm kiếm một giải pháp Cordova. Hoặc, tôi sẽ đơn giản là vô hiệu hóa mọi nút tải xuống nếu nền tảng là Android hoặc iOS.
Tôi sẽ đăng mọi giải pháp khắc phục Cordova hoạt động tại đây, nếu tôi tìm được một cái

Câu trả lời #1

nếu điều bạn muốn đạt được là lưu tệp vào hệ thống tệp, bạn có thể lưu nó với chuỗi base64 vào hệ thống tệp

image = "data:image/png;base64,iVBORw0KGgo... bla bla bla"
Capacitor.Plugins.Filesystem.appendFile({
    data:image,
    path:"directory/image.png",
    directory:"DOCUMENTS"
}).then(c=>{console.log("se escribiooo")})

kết quả của nó là hình ảnh trong hệ thống tệp của bạn (tôi vừa thử mã này trên trình giả lập Android), chỉ cần sử dụng phương thức appendFile thay vì writeFile, và base64 thay vì blob, nếu bạn chỉ có blob thì chỉ cần chuyển nó sang base64

Câu trả lời #2

Chia sẻ cách giải quyết tạm thời của tôi với bạn.

Tôi đang sử dụng phiên bản web của plugin Hệ thống tệp. Không biết liệu đó có phải là giải pháp tốt không nhưng nó giúp giải quyết vấn đề của tôi.

import { FilesystemDirectory, FilesystemEncoding } from '@capacitor/core'
// const { Filesystem } = Plugins // => Doesn't work with blob in native
// Workaround: Use Web-Implementation of plugin
import { FilesystemPluginWeb } from '@capacitor/core/dist/esm/web/filesystem.js'
const Filesystem = new FilesystemPluginWeb()

Bài viết liên quan