使用相机和文件插件在Ionic 4中上传图片

时间:2019-07-01 11:59:55

标签: cordova ionic-framework cordova-plugins ionic4

我正在尝试将Ionic 4中的文件上传到服务器,但收到错误2nd parameter must be blob

但是我已经记录了Blob图片,它正常显示。

我在此https://devdactic.com/ionic-4-image-upload-storage/此链接中关注该指南。

我不需要将其保存到本地存储中,因此我跳过了该部分。

selectImageInGallery() {
    const options: CameraOptions = {
      quality: 100,
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      saveToPhotoAlbum: false
    };
    this.camera.getPicture(options).then(
      imageData => {
        const formData = this.uploadAvatar(imageData);
        this.uploadAvatar(formData);
      },
      err => {
        this.toastService.presentToastBottom('Failed to select the image');
      }
    );
  }

uploadAvatar(imagePath: any) {
    let fileName = '';
    this.file
      .resolveLocalFilesystemUrl(imagePath)
      .then(fileEntry => {
        const { name, nativeURL } = fileEntry;
        const path = nativeURL.substring(0, nativeURL.lastIndexOf('/'));
        fileName = name;
        return this.file.readAsArrayBuffer(path, name);
      })
      .then(buffer => {
        const imgBlob = new Blob([buffer], {
          type: 'image/jpeg'
        });
        console.log(imgBlob);
        const formData: FormData = new FormData();
        formData.append('avatar', imgBlob);
        this.userService.updateAvatar(formData).then(res => {
          console.log(res);
          this.loader.hideLoader();
          // if (res.data.status === 'success') {
          //   this.user = res.data.user;
          // } else if (res.data.status === 'error') {
          //   this.toastService.presentToast(res.data.message);
          // } else {
          //   this.toastService.presentToast('Server Error');
          // }
        });
      });
  }

Service
public async updateAvatar(postData: any) {
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'multipart/form-data',
        'X-Authorization': environment.appKey,
        Authorization: localStorage.getItem('TOKEN_KEY')
      })
    };
    const res = await this.http
      .post(
        environment.apiUrl + 'user/update-profile-picture',
        postData,
        httpOptions
      )
      .toPromise();
    return res as any;
  }

2 个答案:

答案 0 :(得分:1)

您对本教程的关注程度如何?

正如我从看Simon的视频(devdactic作者)的回忆中回忆的那样,在处理图像时会遇到一些麻烦,您需要在系统上至少创建一个临时文件才能发送到其他地方。

首先,您应该完全按照本教程进行操作,然后在开始工作后就可以尝试删除内容。

在教程的第一部分中明确指出:

  • 使用POST请求从其本地路径上传文件

因此,我认为仅删除本教程的大部分内容并不是实现此目标的最佳方法。

先向专家学习,然后再修改。

答案 1 :(得分:0)

    uploadBase64(imageBase64: any) {
    this.loader.showLoader();
    const blobImg = this.dataURItoBlob(imageBase64);
    const formData: FormData = new FormData();
    formData.append('avatar', blobImg, 'image.jpeg');
    this.profileService.updateAvatar(formData).then(res => {
      this.loader.hideLoader();
      if (res.data.status === 'success') {
        this.user.avatar = imageBase64;
      } else if (res.data.status === 'error') {
        this.toastService.presentToast(res.data.message);
      } else {
        this.toastService.presentToast('Server Error');
      }
    });
  }

  dataURItoBlob(dataURI: any) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    let byteString: any;
    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURI.split(',')[1]);
    } else {
      byteString = unescape(dataURI.split(',')[1]);
    }
    // separate out the mime component
    const mimeString = dataURI
      .split(',')[0]
      .split(':')[1]
      .split(';')[0];
    // write the bytes of the string to a typed array
    const ia = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], { type: mimeString });
  }

  async openCertificateUploadPage() {
    const modal = await this.modalCrtl.create({
      component: CertificateUploadPage
    });
    modal.onDidDismiss().then(res => {
      this.getProfile();
    });
    return await modal.present();
  }

这是该问题的解决方案。我知道了。