Corodova file transfer not working after updating

2019-07-24 17:51发布

问题:

Since updating my ionic 2 app to release candidate RC0 the Cordova file transfer plugin is no longer working properly. The server doesn't get any of the parameters (params).

The relevant part of my code looks like this:

        var now = Date.now();
        const ft = new Transfer();
        var options:any;
        options = {
          fileKey: "photo",
          fileName: this.userID + '_' + now + '_' + fileURL.substr(fileURL.lastIndexOf('/') + 1),
          mimeType: "image/jpeg",
          params: {
            user_id: 1, 
            title: this.title,
            item_type: 'P',
            latitude: this.latitude,
            longitude: this.longitude,
            timestamp: this.dateTime},
          headers: {}
        };

        options.headers = headers;

        ft.upload(this.data, encodeURI(API_ENDPOINT + 'photoupload/'), options, true)
          .then((result: any) => {
            this.submiting = false; // Clear submitted flag              
            let alert = this.alertCtrl.create({
              title: 'Done!',
              subTitle: 'Your photo was been uploaded and is now waiting to be approved (this can take up to 3 days). Thank you for contributing to the World Image Archive.',
              buttons: [
                {
                  text: 'Ok',
                  handler: data => {
                  }
                }
              ],
            });
            alert.present(alert);
          })
          .catch((error: any) => {
            console.log('****** PhotoPage: image upload failed with error:'+JSON.stringify(error));
            this.showAlert('Problem Uploading Image', 'Image upload failed');
          });
      });

ft.upload runs, and appears to upload the file, but the server complains that the expected parameters do not exist. The server can also not find the photo data.

This worked fine before upgrading to ionic 2 RC0 from ionic 2 Beta10

The complete ts file looks like this:

import {NavController, Events, AlertController, Platform, LoadingController} from 'ionic-angular';
import {NgZone, Component} from '@angular/core';
import {Camera, Transfer} from 'ionic-native';
import {API_ENDPOINT} from '../../app_settings';
import {DjangoAuth} from '../../providers/djangoAuth';

@Component({
  templateUrl: 'photo.html',
})
export class PhotoPage {

  submitMediaItem:any = {};
  tandc:boolean = false;
  submiting:boolean = false;
  userID:number = 0;
  loading:any;
  data:any;
  zone:any;
  theImage:any;
  showInstructions:boolean = false;
  title:any = "X";
  latitude:any = "";
  longitude:any = "";
  dateTime:any = "";
  event:boolean = false;
  nature:boolean = false;
  architecture:boolean = false;

  progress: number;
  // SEE: https://github.com/dtaalbers/ionic-2-examples/blob/master/file-transfer-upload/app/pages/uploading/uploading.ts

  constructor(public alertCtrl: AlertController,
              public loadingCtrl: LoadingController,
              public nav : NavController,
              public ngzone : NgZone,
              public camera: Camera,
              public events : Events,
              public djangoAuth : DjangoAuth,
              public platform : Platform){
    this.zone = ngzone;

    //this.listenToSubmittedEvents();
  }

  addPhoto(){
    var options = {
      quality: 75,
      //destinationType: navigator.camera.DestinationType.DATA_URL, // For file transfer (rather than display) use FILE_URL
      destinationType: Camera.DestinationType.FILE_URI, // For file transfer (rather than display) use FILE_URL
      sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
      //allowEdit: true,
      encodingType: Camera.EncodingType.JPEG,
      //targetWidth: 1000,
      //targetHeight: 1000,
      //popoverOptions: CameraPopoverOptions,
      saveToPhotoAlbum: false
    };

    Camera.getPicture(options).then((data:any) => {
      //alert('Data='+data);
      //alert('Camera.EncodingType.JPEG='+Camera.EncodingType.JPEG+', Camera.DestinationType.FILE_URI='+Camera.DestinationType.FILE_URI);
      var thisResult = JSON.parse(data);
      //alert('getPicture returned: '+thisResult);
      var metadata = JSON.parse(thisResult.json_metadata);
      this.data = thisResult.filename;
      if (metadata != "{}") {
        //alert('GetPicture Data Returned exif data: '+ thisResult.json_metadata);
        // iOS and Android return the exif and gps differently and I am not converting or accounting for the Lat/Lon reference.
        if (this.platform.is('ios')) {
          //alert('Platform is ios');
          if (metadata && typeof metadata.GPS != 'undefined' && typeof metadata.GPS.Latitude != 'undefined') {
            this.latitude = metadata.GPS.Latitude;
            this.longitude = metadata.GPS.Longitude;
            if (metadata.GPS.LatitudeRef == 'S') this.latitude = -this.latitude;
            if (metadata.GPS.LongitudeRef == 'W') this.longitude = -this.longitude;
            this.dateTime = metadata.Exif.DateTimeOriginal;
            //alert('metadata.GPS.Latitude: ' + metadata.GPS.Latitude + ' metadata.GPS.Longitude: ' + metadata.GPS.Longitude + 'this.Latitude: ' + this.latitude + ' this.Longitude: ' + this.longitude);
            //alert('DateTimeOriginal: ' + metadata.Exif.DateTimeOriginal);
          }
          else
          {
            this.showAlert('Incompatible Image', 'The image you selected does not have location information. Only images with location and date information can be submitted.');
            this.latitude = '';
            this.longitude = '';
            this.dateTime = '';
          }
        }
        else {
          //alert('Platform is not ios');
          if (metadata && typeof metadata.gpsLatitude != 'undefined') {
            this.latitude = metadata.gpsLatitude;
            this.longitude = metadata.gpsLongitude;
            this.dateTime = metadata.Exif.DateTimeOriginal;
            //alert('Lat: ' + metadata.gpsLatitude + ' Lon: ' + metadata.gpsLongitude);
            //alert('DateTimeOriginal: ' + metadata.Exif.DateTimeOriginal);
          }
          else
          {
            this.showAlert('Incompatible Image', 'The image you selected does not have location information. Only images with location and date information can be submitted.');
            this.latitude = '';
            this.longitude = '';
            this.dateTime = '';
          }
        }
      }
      else {
        this.showAlert('Incompatible Image', 'Image does not have location information');
        this.latitude = '';
        this.longitude = '';
        this.dateTime = '';
      }

      this.zone.run(()=> {
        this.theImage = thisResult.filename;
      });
    }, (err:any) => {
      alert('in getPicture err');
      this.submiting = false;
      this.showAlert("Couldn't Get Photo", err);
    });
  }

  onSubmit(form) {
    // Submit the item to YHistory
    if (this.latitude == ''){
      this.showAlert('Incompatible Image', 'The image you selected does not have location information. Only images with location and date information can be submitted.');
      return;
    }

    if (form.valid) {
      if (this.submitMediaItem.title) this.title = this.submitMediaItem.title + ' ';

      // Add category tags to end of title/description
      if (this.event) {
        this.title = this.title + '[event] ';
      }
      if (this.nature) {
        this.title = this.title + '[nature] ';
      }
      if (this.architecture) {
        this.title = this.title + '[architecture] ';
      }

      this.userID = 1;

      this.platform.ready().then(() => {

        if (this.platform.is('cordova')) {

          var fileURL = this.data;

          // Create http headers then do upload
          // false param prevents application/json being added to headers
          this.djangoAuth.createHeaders(false).then((headers) => {

            var now = Date.now();

            const ft = new Transfer();
            var options:any;
            options = {
              fileKey: "photo",
              fileName: this.userID + '_' + now + '_' + fileURL.substr(fileURL.lastIndexOf('/') + 1),
              mimeType: "image/jpeg",
              params: {
                user_id: 1, // This is ignored
                title: this.title,
                item_type: 'P',
                latitude: this.latitude,
                longitude: this.longitude,
                timestamp: this.dateTime},
              headers: {}
            };

            options.headers = headers;

            console.log('****** photo.ts: createHeaders() returned headers: '+ JSON.stringify(headers.toJSON()));
            console.log('****** photo.ts: inside createHeaders().then options: '+JSON.stringify(options));

            this.loading = this.loadingCtrl.create({
              content: 'Submitting photo...',
              spinner: 'crescent'
            });
            this.loading.present();

            // Make sure we are never permanently stuck with the loading widget if something goes wrong with server result
            setTimeout(()=> {
              this.loading.dismiss();
            }, 36000);

            ft.upload(this.data, encodeURI(API_ENDPOINT + 'photoupload/'), options, true)
              .then((result: any) => {
                this.submiting = false; // Clear submitted flag
                // Signify photo submission was successful
                //this.events.publish('submitted:success');
                this.loading.dismiss();
                let alert = this.alertCtrl.create({
                  title: 'Done!',
                  subTitle: 'Your photo was been uploaded and is now waiting to be approved (this can take up to 3 days). Thank you for contributing to the World Image Archive.',
                  buttons: [
                    {
                      text: 'Ok',
                      handler: data => {
                        //this.nav.setRoot(HomePage);
                      }
                    }
                  ],
                });
                alert.present(alert);
                //this.success(result);
              })
              .catch((error: any) => {
                console.log('****** PhotoPage: image upload failed with error:'+JSON.stringify(error));
                this.loading.dismiss();
                this.showAlert('Problem Uploading Image', 'Image upload failed');
                this.submiting = false; // Clear submitted flag
                //this.failed(error);
              });
          });
        }
      });
    }
  }

  showPageInstructions() {
    this.showInstructions = true;
    //this.storage.set(this.DONE_PHOTOS_POPUP, true);
  }

  closeInstructions(){
    this.showInstructions = false;
  }

  showTerms(){
    let alert = this.alertCtrl.create({
      title: 'Terms and Conditions',
      subTitle: "You must not upload any images which are illegal, are offensive, or violate the copyright of others. " +
      "Persistant submission of images which violate these rules will result in your account being terminated.",
      buttons: ['Ok']
    });
    alert.present(alert);
    return;
  }

  categoryHelp() {
    this.showAlert('Image Types','<br />Please select one or more of the following image types:<br /><br />Event (e.g. concerts, earthquakes, riots, weddings, protests, birthday parties, floods, ...)' +
      '<br /><br />Nature (e.g. landscape, sea, fields, rivers, mountains, ...)' +
      '<br /><br />Architecture (e.g. buildings, bridges, roads, all large man made structures...)');
  }

  showAlert(title, subtitle) {
    let alert = this.alertCtrl.create({
      title: title,
      subTitle: subtitle,
      buttons: ['Ok']
    });
    alert.present(alert);
  }
}