I’m unable to upload a photo to my server using Cordova’s file and file-transfer plugin through ionic. I’m able to succesfully capture the photo I need, and make a valid request to the server endpoint that’s expecting my image along with other data, but when I make the request, my payload is sent is as empty, which causes the server to respond with a 500 and ultimately an “error code 3” from the cordova plugin.
I’ve looked around and tried to figure this out, but seem to be stuck. Any help would be appreciated. I’ve tried this on both Android and iOS.
Here’s a snippet of my FileTransfer related code:
$scope.send = function() {
var myImg = $scope.picURL;
var options = new FileUploadOptions();
options.fileKey = "post";
options.chunkedMode = false;
var params = {};
params.message = "HELLO";
options.params = params;
var ft = new FileTransfer();
ft.upload(myImg, encodeURI(API_URL + "/uploadPhoto"), function(e){
$ionicLoading.hide();
alert("upload success!");
},
function(e){
$ionicLoading.hide();
alert("Upload failed!");
}, options);
}
Isn’t the request payload already set as a POST method? I’m able to see the request to the “/uploadPhoto” endpoint reach there successfully on the server (which is a POST endpoint), but the data is empty.
If the “myImg” variable is null, shouldn’t the “options” at least be sent through?
I’m not seeing the payload show up under Safari Web Inspector (iOS Simulator), which is strange because I see all other request payloads being captured correctly under the XHRs folder. In Chrome on the browser, I’m unable to test out this feature as it is dependent on the camera.
However, on my server, I have verified that the POST endpoint is reached and here are some snippets from the request payload (it’s an Express JS server). Hope this is useful in debugging:
body: {},
cookies: { 'connect.sid': 's:t9qzKwdvdVW3VoTiSbHNvwRsOo-6w-8a.gU4NpdEj8GYZjoLjYvpbUPhsQF7X1Ga+okk0Rj5E4aI' },
headers: { host: '**.*.***.***:3003',
'x-requested-with': 'XMLHttpRequest',
accept: '*/*',
'content-type': 'multipart/form-data; boundary=+++++org.apache.cordova.formBoundary',
'content-length': '509065',
'accept-language': 'en-us',
'accept-encoding': 'gzip, deflate',
cookie: 'connect.sid=s%3At9qzKwdvdVW3VoTiSbHNvwRsOo-6w-8a.gU4NpdEj8GYZjoLjYvpbUPhsQF7X1Ga%2Bokk0Rj5E4aI',
connection: 'keep-alive',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_9_5 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B411 (2093456832)' },
I stepped through the CDVFileTransfer.m class to see where it breaks, and it happens at the point where the Image File data is created, i.e. I would assume that the path is not valid? I’ve tried multiple ways to access the full path of the file, but perhaps I’m not accessing that correctly?
This is what my latest attempt looks like with regards to getting the ‘correct’ image uri:
I’ve removed and reinstalled the last version of cordova-plugin-file and cordova-plugin-file-transfer, I’ve tried to modify the upload call to match the criteria in the cordova documentation:
Hello everyone,
I’m trying to build an app with a Capture and FileTransfer plugins.
My Capture feature works well so I’m able to record videos but when I try to send them to my server it doesn’t work (error code 3) and I can’t figure out why.
Any help would be appreciate. Here’s my test controller :
here’s my upload video function. It worked. I recommend you the Connection: close option and the event listener deviceready. Hope it works also for you.
S
function uploadVideo() {
document.addEventListener('deviceready', function () {
var fileURL = sessionStorage.getItem('lastVideoUploaded');
var alertPopup = $ionicPopup.alert({
title: 'Video about to upload!',
template: fileURL
});
var fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
if(fileURL.substring(0, 4) == "http") {
fileURL = encodeURI(fileURL);
}
sessionStorage.setItem('profilePhoto', fileName);
function win(r) {
var alertPopup = $ionicPopup.alert({
title: 'Video Uploaded!',
template: "Don't worry, you can always change it! Now save your profile!"
});
$state.go('tab.UMP');
}
function fail(error) {
var alertPopup = $ionicPopup.alert({
title: 'Errore!',
template: JSON.stringify(error)
});
}
var uri = encodeURI("http://yourpage.php");
var params = {};
params.comesFrom = "challenge";
params.user = $scope.data.userCompleto;
var options = new FileUploadOptions();
options.fileKey = "fileToSave";
options.fileName = fileName;
options.chunkedMode = false;
options.headers = {
Connection: "close"
}
options.mimeType = "video/mpeg"; //retrieve the correct mime type
options.params = params;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
} else {
loadingStatus.increment();
}
};
ft.upload(fileURL, uri, win, fail, options);
}, false);
}
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callBack) {
callBack(null, 'destinationFolder');
},
you can also pass in folder name in params to the destination function from the app and access it using req.body
make sure that folder already exists and then pass it to the callBack
you can use normal file functions to check whether folder exists and create it if it doesn’t exist and then pass it to the callBack function
filename: function (req, file, callBack) {
callBack(null, 'someName');
}
});
var upload = multer({ storage: storage }).single('file');
// single(‘file’) - this is the filekey in the options parameter passed in cordova-file-transfer call from app