【问题标题】:How to use FormData for ionic file upload如何使用 FormData 进行离子文件上传
【发布时间】:2018-05-08 16:55:04
【问题描述】:

我想通过 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");
}

【问题讨论】:

    标签: ionic-framework alfresco


    【解决方案1】:

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

    我将文件作为 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);
    }
    

    【讨论】:

    • "类型 'string | ArrayBuffer | null' 不可分配给类型 'BlobPart'"
    • 请注意:这会将整个文件读入本地内存,对于大文件可能会导致设备崩溃
    【解决方案2】:

    我认为在您的情况下没有必要使用 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
        };
      }
    }
    

    【讨论】:

    • 我可以做同样的发送视频文件吗?
    • 这不应该被接受为正确答案,你不能上传大图或doc或其他文件类型
    • 感谢我使用了你的代码,但我失去了图片质量。
    【解决方案3】:

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

    【讨论】:

    • 谢谢,但在我的网络服务器中,我的正文来自数据(文件数据,数字)而不是参数
    • 我找不到在 fileTransfer API 中传递表单数据的任何选项。让我们看看是否有其他人更新了一些东西,但我猜你需要更新 API。
    • 如何使用其他 ionic 插件或 HttpClient 发送表单数据
    【解决方案4】:

    我在将图像上传到 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 -> https://stackoverflow.com/a/16245768/5232022

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

    【讨论】:

      猜你喜欢
      • 2014-01-29
      • 2018-03-18
      • 2018-02-27
      • 2017-08-30
      • 2019-04-28
      • 2012-03-26
      相关资源
      最近更新 更多