Hello
Is there a way to do POST request with multipart/form-data without selecting the file manually by using file input, but giving already known local file path? As I’ve read - because of security measures you cannot specify the local path without using file input. Are there alternative ways to deliver the file with other form data with one request?
Hi Reinis,
Did you solve this problem ? Because I had a same issue and seems to I got stuck here
Use cordova file transfer plugin:
url = “http://mysite.com/upload.php”;
filepath = "file://…/image.jpg"
var options = {
fileKey: “myImage”,
httpMethod: “POST”,
mimeType: “image/jpeg”,
params: {myDescription: “bla bla”, rating: 5},
chunkedMode: true
}
$cordovaFileTransfer.upload(url, filepath, options, true).then(function(…){…});
Hi Reinis,
Thanks for your help.This way I can push image to web service but this time I cannot take params values at server side. I am using node.js and express.js based web service. All data of image can come with request but params field never came. I tried one up object (I mean req.body or req.file even req) and params at nowhere.
Which server side technology you are using and how can get params value field ?
Thanks.
you can get the file via cordova file plugin and add it with the javascript FormData-API
Ok, how can I combine these two things. You are saying, put form Data object to cordova file plugin params values ?
nope if you are using file-transfer plugin you do not need the FormData --> but you need the valid path to the local file, which you can get via file-plugin (requestLocalFileSystem --> getFile):
//mobile upload
var ft = new FileTransfer(),
ftOptions = new FileUploadOptions();
ftOptions.fileKey = 'file';
ftOptions.fileName = PATH.substr(params.lastIndexOf('/') + 1); // extract file name from PATH
ftOptions.mimeType = 'image/jpeg';
ftOptions.httpMethod = 'POST';
ft.upload(PATH, UPLOADURL, function (res) {
//upload success
}, function () {
//upload failed
}, ftOptions);
If you want to upload files via a direct POST-Request your need to create formData-object set contenttype to ‘application/x-www-form-urlencoded’. But i think this will only work on non-mobile environment
//DEVICE: cordova-plugin-file-transfer // camera FILE_URI
function win() {
console.log("uploaded");
}
function fail() {
console.log("not uploaded");
}
let filename = result.nativeURL.substr(result.nativeURL.lastIndexOf("/") + 1);
let options = new FileUploadOptions();
options.fileKey = "myfile";
options.fileName = filename;
options.mimeType = "image/jpeg";
let params = {
filename: "myfilename.jpg",
folder: "myFolder"
};
options.params = params;
let ft = new FileTransfer();
ft.upload(result.nativeURL, "http://SERVERIP:PORT/file/upload", win, fail, options);
//BROWSER camera-api-mock for browser
private getPicture(successCallback: any, errorCallback: any, options: any): void {
var callDialog = function(dialog, callback) {
dialog.addEventListener("change", function() {
callback(dialog);
}, false);
dialog.click();
};
var acceptTypes: any = ".jpg";
var dialog = document.createElement("input");
dialog.type = "file";
if (angular.isArray(acceptTypes)) {
dialog.accept = acceptTypes.join(",");
} else if (angular.isString(acceptTypes)) {
dialog.accept = acceptTypes;
}
callDialog(dialog, successCallback);
}
//and then:
let formData = new FormData();
formData.append("filename", "myVarFilename.jpg"); //filename first, otherwise req.body is empty in multer
formData.append("folder", "myFolder");
formData.append("myfile", dialog.files[0]); //dialog is the result from camera-api-mock
$http({
url: "http://SERVERIP:PORT/file/upload",
method: "POST",
data: formData,
headers: {"Content-Type": undefined}
}).then(() => {
console.log("success");
}).catch(() => {
console.log("error");
});
//SERVERSIDE Nodejs/express 4 with multer
let multer = require ("multer");
let mkdirp = require ("mkdirp");
....
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended: false}));
app.use(cors());
let imagestorage = multer.diskStorage({
destination: (req, file, cb) => {
let newDestination = path.resolve(__dirname, "uploads", "images", req.body.folder);
mkdirp.sync(newDestination);
cb (null, newDestination);
},
filename: (req, file, cb) => {
let getFileExt = (fileName) => {
var fileExt = fileName.split(".");
if ( fileExt.length === 1 || ( fileExt[0] === "" && fileExt.length === 2 ) ) {
return "";
}
return fileExt.pop();
};
cb(null, req.body.filename); // + "_" + Date.now() + "." + getFileExt(file.originalname));
}
});
let multerUpload = multer({ storage: imagestorage }).single("myfile");
app.use(multerUpload);
...
app.post("file/upload", (req: any, res: any) => {
console.log("look into uploads-folder ;-)");
console.log(req.body); //params in here...
console.log(req.file); //saved file information
res.status(200).send(req.file);
});
Yes U r right it will work only in non-mobile environment.
Solutions to this? I’m with the same problem. Using http://ngcordova.com/docs/plugins/fileTransfer/ I get error 3
hi can u please suggest me something on this below code
this.camera.getPicture(options).then((imagePath) => {
if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
this.formData.append('general_canvas',imagePath);
});
the below is upload
let body: string = JSON.stringify({'formData': this.formData});
// type: 'application/json',
let headers: any = new Headers({'Content-Type': 'multipart/form-data'}),
options: any = new RequestOptions({ headers: headers }),
url: any = this.uploadUrl;
this.http.post(url,this.formData, options).map(res => res.json())
.subscribe((data) => {