问题
In my phonegap app I take a picture with my camera and it works as expected.
Then, I'd like to send it to my server. I see that sending the base64 encoded string is a bad practice and I figured the best solution is using the file transfer plugin.
So, I added the plugin and I wrote this:
function onPhotoURISuccess(imageURI) {
try{
var url = "myserver/addPhoto";
alert(url);
var options = new FileUploadOptions();
options.chunkedMode = false;
options.fileKey = "recFile";
var imagefilename = imageURI;
options.fileName = imagefilename;
options.mimeType = "image/jpeg";
options.params = { "token": APP.TOKEN};
var ft = new FileTransfer();
alert(imagefilename);
ft.upload(imageURI, url, win, fail, options);
}
catch (err) {
alert(err.message);
}
}
In the last line in the try branch, I get the error FileTransferError.FILE_NOT_FOUND_ERR.
In the alert before this line, I show in the alert the path (imagefilename variable). If I try to go manually in that path in my Android device, I can't find it. The path is file:///storage/emulated/0/Android/data/com.My.App/cache/1505307795417.jpg
So, I tried to set the option
saveToPhotoAlbum: true
to check if the image is saved and I correctly see the photo in my album. I don't know why I get the error while sending it, can be the path wrong?
I don't think the problem is server side, since I can't even see the request in the server log.
UPDATE:
I also tried this after Anuj T suggestion, but the result is still the same:
function onPhotoURISuccess(imageURI) {
var filepath;
window.resolveLocalFileSystemURL(imageURI, function success(fileEntry) {
// Do something with the FileEntry object, like write to it, upload it, etc.
// writeFile(fileEntry, imageURI);
filepath = fileEntry.fullPath;
alert("got file: " + fileEntry.fullPath);
// displayFileData(fileEntry.nativeURL, "Native URL");
try {
var url = "myUrl";
alert(url);
var options = new FileUploadOptions();
options.chunkedMode = false;
options.fileKey = "recFile";
var imagefilename = filepath;
options.fileName = imagefilename;
options.mimeType = "image/jpeg";
options.params = { "token": APP.TOKEN }; // if we need to send parameters to the server request
var ft = new FileTransfer();
alert(imagefilename);
alert(imageURI);
ft.upload(filepath, url, win, fail, options);
}
catch (err) {
alert(err.message);
}
}, function () {
// If don't get the FileEntry (which may happen when testing
// on some emulators), copy to a new FileEntry.
alert("file system fail");
createNewFileEntry(imgUri);
});
}
UPDATE 2:
This is my server side code.
internal GenericResponse AddChiusuraPhoto(string token)
{
Utility.Logger("AddChiusuraPhoto");
var gr = new GenericResponse();
if (CheckToken(token, out IS_UTENZE utente))
{
try
{
var md5 = new md5Manager();
HttpPostedFile file = HttpContext.Current.Request.Files["recFile"];
if (file == null)
return null;
string targetFilePath = @"C:\ProgramData\" + file.FileName;
file.SaveAs(targetFilePath);
Utility.Logger("[AddChiusuraPhoto] Returning lista ");
return gr;
}
catch (Exception ex)
{
gr.ESITO = "[KO]";
gr.MESSAGGIO = ex.ToSafeString();
Utility.Logger("AddChiusuraPhoto " + gr.MESSAGGIO);
}
}
else
{
gr.ESITO = "[KO]";
gr.MESSAGGIO = "Utente non loggato, impossibile effettuare il logout.";
Utility.Logger("AddChiusuraPhoto " + gr.MESSAGGIO);
}
return gr;
}
Note that this is a WCF. This is the addressing part:
[OperationContract]
[WebInvoke(UriTemplate = "chiusure/addPhoto", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
GenericResponse AddChiusuraPhoto(string token);
回答1:
You need to take a picture and get a FileEntry Object
If you need to use a FileEntry object, set the destinationType to Camera.DestinationType.FILE_URI in your CameraOptions object
UPDATED CODE
function getPicture(){
var srcType = Camera.PictureSourceType.CAMERA;
var options = setOptions(srcType);
//var func = createNewFileEntry;
navigator.camera.getPicture(function cameraSuccess(imageUri) {
//displayImage(imageUri);
// You may choose to copy the picture, save it somewhere, or upload.
//func(imageUri);
var filename = imageUri.substr(imageUri.lastIndexOf('/') + 1);
window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {
// Do something with the FileEntry object, like write to it, upload it, etc.
// writeFile(fileEntry, imgUri);
console.log("got file: " + dirEntry.fullPath);
console.log("file name " + filename);
// JPEG file
dirEntry.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {
// Do something with it, like write to it, upload it, etc.
// writeFile(fileEntry, imgUri);
console.log("got file: " + fileEntry.fullPath);
// displayFileData(fileEntry.fullPath, "File copied to");
upload(fileEntry);
}, onErrorCreateFile);
// displayFileData(fileEntry.nativeURL, "Native URL");
}, function () {
// If don't get the FileEntry (which may happen when testing
// on some emulators), copy to a new FileEntry.
//createNewFileEntry(imgUri);
});
//console.log(imageUri);
}, function cameraError(error) {
console.debug("Unable to obtain picture: " + error, "app");
}, options);
};
set option function.
function setOptions(srcType) {
var options = {
// Some common settings are 20, 50, and 100
quality: 50,
destinationType: Camera.DestinationType.NATIVE_URI ,
// In this app, dynamically set the picture source, Camera or photo gallery
sourceType: srcType,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE,
allowEdit: false,
saveToPhotoAlbum:false,
correctOrientation: true //Corrects Android orientation quirks
};
return options;
}
See the detail explanation here.
To Upload the file to the server
function upload(fileEntry) {
var fileURL = fileEntry.toURL();
var success = function (r) {
console.log("Successful upload..." + JSON.stringify(r));
console.log("Code = " + JSON.stringify(r.responseCode));
alert(JSON.stringify(r.response));
// displayFileData(fileEntry.fullPath + " (content uploaded to server)");
};
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
console.log("Error= " + error);
};
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.mimeType = "text/plain";
var params = {};
params.value1 = "test";
params.value2 = "param";
options.params = params;
var SERVER = "http://posttestserver.com/post.php";
var ft = new FileTransfer();
// SERVER must be a URL that can handle the request, like
// http://some.server.com/upload.php
ft.upload(fileURL, encodeURI(SERVER), success, fail, options);
}
when you get the success alert you can also check your params uploaded to the server or not, you will receive the link in success.
Hope this help.
来源:https://stackoverflow.com/questions/46199761/cordova-phonegap-filetransfererror-file-not-found-err-with-file-transfer-plugin