如何使用FormData进行ionic文件上传

How to use FormData for ionic file upload

我想使用 fileTransfer(ionic 3 ) 或其他函数将表单数据发送到服务器

var form = new FormData();
form.append("filedata", base64File);
form.append("numDeclaration", "01012018");

let options: FileUploadOptions = {
          fileKey: 'filedata',
          fileName: imageName,
          chunkedMode: false,
          mimeType: "image/jpeg",
          headers: {}
        }

fileTransfer.upload(base64File, 'http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/f3589d6b-82db-44d2-9b6d-89a3e7e57442/children?alf_ticket=' + localStorage.getItem('token'), options).then((data) => {
     console.log(data + " Uploaded Successfully");
}

您不能使用 fileTransfer API 发送表单数据。如果你想沿着文件对象传递额外的数据,你可以在 FileUploadOptions 中使用 params 键。

我认为在你的情况下没有必要使用cordova文件传输插件。您可以通过 angular HttpClient (XMLHttpRequest) 发送 FormData。您只需要将 base64 字符串转换为 blob 对象,您可以将其进一步上传到您的服务器。

class UploadService {
  constructor(private httpClient: HttpClient) {
    const base64 = 'data:image/png;base64,';
    this.uploadBase64(base64, 'image.png').subscribe(() => {});
  }

  uploadBase64(base64: string, filename: string): Observable<any> {
    const blob = this.convertBase64ToBlob(base64);
    const fd = new FormData();

    fd.append('filedata', blob, filename);
    fd.append('numDeclaration', '01012018');

    return this.httpClient.post('url', fd)
      .pipe(catchError((error: any) => Observable.throw(error.json())));
  }

  private convertBase64ToBlob(base64: string) {
    const info = this.getInfoFromBase64(base64);
    const sliceSize = 512;
    const byteCharacters = window.atob(info.rawBase64);
    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
      const byteNumbers = new Array(slice.length);

      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }

      byteArrays.push(new Uint8Array(byteNumbers));
    }

    return new Blob(byteArrays, { type: info.mime });
  }

  private getInfoFromBase64(base64: string) {
    const meta = base64.split(',')[0];
    const rawBase64 = base64.split(',')[1].replace(/\s/g, '');
    const mime = /:([^;]+);/.exec(meta)[1];
    const extension = /\/([^;]+);/.exec(meta)[1];

    return {
      mime,
      extension,
      meta,
      rawBase64
    };
  }
}

我遇到了同样的问题,不想使用 ionic 文件传输插件。

我将文件读取为 blob 并将其添加到 formData 中。对我来说很好。

private fileReader(file: any) {
  const reader = new FileReader();
  reader.onloadend = () => {
    const formData = new FormData();
    const blobFile = new Blob([reader.result], { type: file.type });
    formData.append("file", blobFile, "filename");
    // POST formData call
  };
  reader.readAsArrayBuffer(file);
}

我在将图像上传到 Azure Blob 存储时遇到问题,因此在这方面花费了相当多的时间后,我得出了这个解决方案。它具有 pc 和 android/ios 的逻辑,因为它们的工作方式不同。请看下面的代码。

send to blob storage

     if (Capacitor.platform === 'ios' || Capacitor.platform === 'android') {
              const blob = this.base64ToBlob(file);
              const fileToUpload = blob;
              const xhr = new XMLHttpRequest();
              xhr.open('PUT', path);
              xhr.onload = () => {
                console.log('sent to azure blob storage');
              };
              xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
              xhr.setRequestHeader('Content-Type', 'image/jpeg');

              xhr.send(fileToUpload);
            } else { // PC
              this.http.put(path, file, {
                headers: new HttpHeaders({
                  'x-ms-blob-type': 'BlockBlob',
                  'Content-Type': 'image/jpeg',
                  'x-ms-blob-content-type': file.type,
                  'X-Skip-Interceptor': ''
                })
              }).subscribe(() => {
                console.log(`APP: ${fileName} uploaded to blob storage`);
              });
            }

base64ToBlob function ->

      base64ToBlob(file) {
    let b64Data = file.base64Image;
    const contentType = 'image/jpeg';
    const sliceSize = 512;

    b64Data = b64Data.replace(/data\:image\/(jpeg|jpg|png)\;base64\,/gi, '');

    const byteCharacters = atob(b64Data); // decode base64

    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);

      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }

      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    const blob = new Blob(byteArrays, { type: contentType });
    return blob;
  }