0
votes

I am trying to upload an image to the server and I first tried with this method : Trouble to upload images with FileTransfer But I couldn't find out the problem.

Now I am using another function on the server which is working fine with the iOS application but not with the android ionic one.

The server do receive the HTTP POST request but I can't find how to get the image sent.

Here is the application code :

  takePhoto(value){

const options: CameraOptions = {
  quality: 100,
  destinationType: this.camera.DestinationType.DATA_URL,
  encodingType: this.camera.EncodingType.PNG,
  mediaType: this.camera.MediaType.PICTURE,
  correctOrientation : true,
  allowEdit:true,
  targetWidth: 500,
  targetHeight: 500,
  sourceType : value,
  saveToPhotoAlbum: true


}

this.camera.getPicture(options).then((imageData) => {
  let base64Image = 'data:image/jpg;base64,' + imageData;
  console.log(base64Image)
  const fileTransfer: FileTransferObject = this.transfer.create();
  let formData = new FormData();
  formData.append('photo', imageData);

  var headers = new Headers();
  //headers.append('Content-Type', 'multipart/form-data; boundary=uwhQ9Ho7y873Ha');
  //headers.append('Content-Disposition', 'form-data');
  //let options = new RequestOptions({ headers: headers });
  var options : FileUploadOptions = {
    fileKey: "photo",
    chunkedMode: false,
    mimeType: "multipart/form-data",
  };

  //tried this way
  this.http.post("http://51.255.174.99:90/add/photo/" + this.user._id,
  formData, options).subscribe(data => {
    console.log("data = " + data);
  });

  //and this way 
  fileTransfer.upload(imageData,"http://XX.XXX.XXX.XX:90/add/photo/" + this.user._id, options).then((data) => {
      console.log("data = " + data);
      this.presentToasti("It worked !");

  }, (err) => {
      console.log("upload failed");
    })

  }, (err) => {
    this.presentToasti(err);
});
}
presentToasti(msg) {
let toast = this.toastCtrl.create({
  message: msg,
  duration: 3000,
  position: 'bottom'
});

toast.onDidDismiss(() => {
  console.log('Dismissed toast');
});
toast.present();
}

and here the server code (I won't touch it, it's working as it should on iOS without any problem) :

exports.addphoto = function (req, res) {
  var phone = require('phone');

  var wine={};
  var ObjectID = require('mongodb').ObjectID;
  var form = new formidable.IncomingForm();
  console.log(form);
  var size=0;
  var retour={};

form.parse(req, function(err, fields, files) {
  if(typeof files['photo'] !== "undefined" && files['photo']!= ""){
        size = files['photo']['size'];
  }else{
        size=0;
  }
  console.log('files:'+JSON.stringify(files['photo']['size']));
});
        console.log(size);
form.on('end', function (fields, files) {

if(typeof this.openedFiles[0]!=="undefined"){
    var temp_path = this.openedFiles[0].path;
    console.log("temp path : "+temp_path);
    if(size>0){
        console.log('bonjour');
      var file_name = req.params.id+".png";
      var new_location = "/var/xxxxx/public/upload/photoprofil/";
      im.resize({
          srcData: fs.readFileSync(temp_path, 'binary'),
          dstPath: temp_path,
          width:   500
      },function(err, stdout, stderr){
        if (err) throw err

        fs.copy(temp_path, new_location + file_name, function (err) {
        if (err) {
                    console.log("erreur : photo de profil non ajoutee");
                    retour['photo']='erreur';
                    res.send(retour);

        } else {
                    console.log("photo de profil ajoutee");
                    retour['photo']='';
                    res.send(retour);
        }
      });
     });

    }
    else{
        retour['photo']='pas de photo';
        res.send(retour);
    }
}else{
        res.send(retour);
}
});
}

Console.log with fileTransfer.upload method :

{ 'content-type': 'multipart/form-data; boundary=+++++',   
'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 8.0.0; ONEPLUS A5010 Build/OPR1.170623.032)',   
host: 'XX.XXX.XXX.XX:90',   
connection: 'Keep-Alive',   
'accept-encoding': 'gzip',   
'content-length': '0' } 
{} 
form {"domain":null,"_events{},"_eventsCount":0,"error":null,"ended":false,"maxFields":1000,"maxFieldsSize":2097152,"keepExtensions":false,"uploadDir":"/tmp","encoding":"utf8","headers":null,"type":null,"hash":false,"multiples":false,"bytesReceived":null,"bytesExpected":null,"_parser":null,"_flushing":0,"_fieldsSize":0,"openedFiles":[]} 
{} 
files:0 
POST /add/photo/5a1fd1a89a6f09412b6a74d7 200 23.479 ms - 2 

Console.log with this.http.post method :

GET /upload/photoprofil/5a1fd1a89a6f09412b6a74d7.jpg 304 1.075 ms - -
{ host: 'XX.XXX.XXX.XX:90',
connection: 'keep-alive',
'content-length': '345852',
accept: 'application/json, text/plain, */*',
origin: 'file://',
'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; ONEPLUS A5010 Build/OPR1.170623.032; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryaAt6z22k3aTPNeCt',
'accept-encoding': 'gzip, deflate',
'accept-language': 'fr-FR,en-US;q=0.9',
'x-requested-with': 'io.ionic.starter' 
{}
form {"domain":null,"_events{},"_eventsCount":0,"error":null,"ended":false,"maxFields":1000,"maxFieldsSize":2097152,"keepExtensions":false,"uploadDir":"/tmp","encoding":"utf-8","headers":null,"type":null,"hash":false,"multiples":false,"bytesReceived":null,"bytesExpected":null,"_parser":null,"_flushing":0,"_fieldsSize":0,"openedFiles":[]}
{}
files:0
POST /add/photo/5a1fd1a89a6f09412b6a74d7 200 333.681 ms - 2

As you can see, with the this.http.post method, there is a content-length that looks like the image uploaded. but the console.log('files'+JSON.stringify(files['photo']['size'])); does not show the size of the file as it does when we do it with the iOS application.

Sorry for the indentation style, I can't find my way with Stackoverflow's way of handling code.

1
Could you post a Minimal, Complete, and Verifiable example using a tool like Plunker?Andrew Roth

1 Answers

0
votes
 destinationType: this.camera.DestinationType.FILE_URI,

Use file uri instead of data url when setting up your camera. Then use the method below.

fileTransfer.upload(imageData,"http://XX.XXX.XXX.XX:90/add/photo/" + this.user._id, options).then((data) => {
  console.log("data = " + data);
  this.presentToasti("It worked !");

  }, (err) => {
      console.log("upload failed");
    })

  }, (err) => {
    this.presentToasti(err);
});