how to do mulitpart request from cordova - javascript

I have to submit form with an image + some additional form fields (mulitipart form submission request).
I have tried this
function upload() {
var img = document.getElementById('image');
var imageURI = img.value;
var options = new FileUploadOptions();
options.fileKey = "photo";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
var params = new Object();
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, "https://www.example.com/upload.php", win, fail,
options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
html is
<input type="file" id="userImage" name="photo">
but it is returning error code 1
and image path is fakepat\1089001
it is also not getting picture name instead a number is showing?
so how do i get image path from input text box?
If i hard code the image (only for testing) in src then request
error code 1
undefined varailbe image
Remember i have to submit image in base64 url

Additional form data would be sent in your params object. Yours is blank now, but you could do
options.params.formkey1 = value1;
options.params.formkey2 = value2;
As for your second question (and I'd try to keep things limited to one question at a time), you need to pass the path of the file on the device. See the docs for File Transfer.
Finally, you don't need to use base64 to upload the data. I'd avoid that as it is bigger than binary data. Just let FileTransfer push up the binary data. It was built to do so.

Related

Get filename and length from blob stream

I am using websockets to send a file from my c# server to my browser. I added the file name and filebytelength along with the file in the bytestream.
My c# code to include file name in the byte stream
string filename = "#\C:\Users\Username\Downloads\RAW1MB data.txt";
string shortName = System.IO.Path.GetFileName(FileName);
byte[] fileNameByte = Encoding.UTF8.GetBytes(shortName);
byte[] fileNamelen = BitConverter.GetBytes(shortName.Length);
byte[] filedata = File.ReadAllBytes(FileName);
byte[] senddata = new byte[4 + fileNameByte.Length + filedata.Length];
fileNamelen.CopyTo(senddata, 0);
fileNameByte.CopyTo(senddata, 4);
filedata.CopyTo(senddata, 4 + fileNameByte.Length);
await webSocket.SendAsync(new ArraySegment<byte>(senddata,0,senddata.Length),WebSocketMessageType.Binary,true,CancellationToken.None );
This is my Javascript included in my HTML
websocket.onmessage = function (e) {
if(e.data instanceof Blob){
window.alert("Getting file");
var filedata = e.data;
var filenameLen = filedata.slice(0,4);
Console.log(filenamelen);// I am getting Blob{ size: 4 ,type: ""}
}
else{
writeToScreen("<span>RESPONSE: " + e.data + "</span>");
}
};
From the console.log I am getting Blob{ size:4,type :""}.
How do I get the integer and string from first 4 bytes and the following respectively?
So without getting the filenamelen I am unable to get the filename as well.

Google script xls attachment not displaying

any thoughts as to why this script emails an attachment but the attachment is not the correct spreadsheet, and looks like some sort of google error page.
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=xlsx";
Logger.log(url);
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(ss.getName() + ".xlsx");
MailApp.sendEmail("youremail#email.com", "Google Sheet to Excel", "The XLSX file is attached", {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
}
I guess API has changed. You can try Drive REST API(v3) instead. Replace
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=xlsx";
var params = { ... };
var blob = UrlFetchApp.fetch(url, params).getBlob();
to
var url = "https://www.googleapis.com/drive/v3/files/" + ss.getId() +
"/export?mimeType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&key=" +
"{your API key}";
var blob = UrlFetchApp.fetch(url).getBlob();
I tested and it worked. Of course you first should get your own API key, etc, at API Manager. Then you can try some APIs like simple GET requests at APIs Explorer. Or you can try some APIs, in this case Files: export, also at the documentation page itself, but notice that you cannot try your own API key here.
This is the updated code that #sangbok helped with:
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var sheet = DriveApp.getFileById(ss.getId());
// sets sharing to public - to send out email.
sheet.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
var url = "https://www.googleapis.com/drive/v3/files/" + ss.getId() + "/export?mimeType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&key=" + "YOURAPIKEYGOESHERE4";
var blob = UrlFetchApp.fetch(url).getBlob();
Logger.log(url);
blob.setName(ss.getName() + ".xlsx");
var now = new Date();
MailApp.sendEmail("YOUREMAILADDRESSGOESHERE", "EMAIL SUBJECT " + now , "EMAIL BODY " + now , {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
// returns the file back to Private access
sheet.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.EDIT);
}

How to send image file in inputstream format to server using XMLHttpRequest object

I have four parameters in webservice. The service is working gud i have tested using android application. But the same thing i cant do in phonegap.
Parameters : name,emailid,pass and imagefile. Image was in format of base64png. In server side i am receiving as Inputstream. Looking for help to send as in binary format.
body+= ServiceHttpHeader('name',name1);
body+= ServiceHttpHeader('emailid',emailid1);
body+= ServiceHttpHeader('pass',pass1);
body +='Content-Disposition: form-data; name=imagedetails;'
body += 'filename='+imagedetails+'\r\n';
body += "Content-Type: application/octet-stream\r\n\r\n ";
body +=imgdetailurl+'\r\n';
body += '--' + boundary + '--';
ImageUploadRequest.setRequestHeader('Cache-Control', 'no-cache');
ImageUploadRequest.send(body);
Phonegap has its own API to upload images to a server.
One solution can be that you upload the image to the server first. On successful upload, you pass all the other parameters, along with the path of the file on the server, to another script, to perform whatever processing you want to be done there.
Phonegap's documentation says that one should not use base64 encoded images for upload, because that often causes an error for the latest high res camera images. Use FILE_URI instead. You can read more here.
http://docs.phonegap.com/en/1.2.0/phonegap_file_file.md.html#FileTransfer
http://docs.phonegap.com/en/2.6.0/cordova_camera_camera.md.html#Camera (the documentation for camera.getPicture())
Example
function uploadPhotoToServer(imageURI)
{
var options = new FileUploadOptions();
options.fileKey="img_file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
window.localStorage.setItem("upload_file_name",options.fileName);
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("<your image upload script url>"), onUploadSuccess, onFail, options);
}
function onUploadSuccess(r)
{
var filename = window.localStorage.getItem("upload_file_name");
file_path_on_server = "path/to/images/folder"+filename;
// other parameters
var email = <the email Id> ;
var name = <the name>;
var parameters = "name="+name+"&email="+email+"&img_path="+file_path_on_server;
$.ajax({
url: <your current script url>,
data: parameters ,
dataType: "jsonp",
timeout:10000,
success:function(json) {
alert(JSON.stringify(json, undefined,2));
},
error:function() {
alert("Error");
},
type:"GET"
});
function onFail()
{
alert("Error");
}
Hope this helps.

Get filename from URL without it in JavaScript

How can I get the filename from a given URL in PhoneGap?
In JavaScript, I used something like this:
var uri = encodeURI("http://www.openerpspain.com/descargas-documentacion?download=2");
My application downloads the file, but I have to manually set the file name. To illustrate, when I call
onclick="descarga('http://www.openerpspain.com/descargas-documentacion?download=2')"
this function is run:
function descarga(URL){
var rutaarchivo = "file:///sdcard/data/com.protocolo/test1.pdf";
alert(rutaarchivo);
var filetransfer = new FileTransfer();
filetransfer.download(URL, rutaarchivo,
function(entry){
alert("Download complete : " + entry.fullPath);
},function(error) {
alert("download error source " + error.source);
});
}
This saves the download to ../com.protocolo, and its filename is test.pdf. I want to be able to save it as the name it is set as on the server (*manual_openerp.230209.pdf*) at the real URL, *...//www.openerpspain.com/descargas/manual_openerp.230209.pdf*.
How do I do that?
String fileName = url.substring(url.lastIndexOf('/') + 1);
where url is the complete path of your file.
Use:
url="file:///sdcard/data/com.protocolo/test1.pdf?getVar=value";
url.replace(/\?.*$/,"").replace(/.*\//,"");
This is basically asking How to get the file name from a full path using JavaScript?. Here, the solution was:
var filename = url.replace(/^.*[\\\/]/, '');
I added in my URLs parameters. Then in PhoneGap I used:
function getParameterByName( name,href ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( href );
if( results == null )
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
Called from :
var filename = getParameterByName ("nombrefichero", url);
So this way I can get example.pdf from:
http://www.download.com/fake/example.pdf?nombrefichero=example.pdf
And then I can download it, and save it where I want.

File-Upload via local file path

Is there a way for enabling file upload via file path?
The default HTML file upload control displays a disabled textbox and a button. Is it possible via JS or something to upload a file when the user pastes the path to the file into a textbox?
This webpage is within a corporate intranet.
No, such thing is not possible in web application using ordinary HTML/JavaScript - period.
The one and only way for user to choose file is via the file dialog opened by clicking the browse button of the <input type="file" /> element.
The only shortcut possible is that JS can open the file dialog automatically, but still - that's the only way for user to choose what file to upload.
There are some small possibilities to do that within a trusted network. Not exactly the same, but still a very similar question: Local file access with javascript
I have done the file uploading using below code in electron app
if (window.FormData !== undefined) {
var formData = new FormData();
let response = await fetch(path); // give local file path stored at appdata folder
let data = await response.blob();
formData.append("file", new File([data], "YourfileName"))
let _url = "api/webservice url";
$.ajax({
type: "POST",
url: _url,
contentType: false,
processData: false,
data: formData,
success: function (result) {
console.log(result);
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
console.log(err);
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
At server side (C# Code)
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
// extract file name and file contents
var fileNameParam = provider.Contents[0].Headers.ContentDisposition.Parameters
.FirstOrDefault(p => p.Name.ToLower() == "filename");
string fileName = (fileNameParam == null) ? "" : ileNameParam.Value.Trim('"');
var divs = fileName.Split('.').ToList();
var ext = divs.LastOrDefault();
byte[] file = await provider.Contents[0].ReadAsByteArrayAsync();
// Here you can use EF with an entity with a byte[] property, or
// an stored procedure with a varbinary parameter to insert the
// data into the DB
var fileVM = new FileViewModel
{
AttachmentType = AttachmentTypeEnum.File,
FileName = fileName,
FileExtension = ext,
ContentType = MimeMapping.GetMimeMapping(fileName),
ContentLength = file.Length,
ContentByte = file,
};

Categories