I need the sendAsBinary() function in javascript, but it seems that Chrome has removed it natively. On the Mozilla MDN (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), they provide a custom function which extends the XMLHttpRequest prototype:
if(!XMLHttpRequest.prototype.sendAsBinary) {
XMLHttpRequest.prototype.sendAsBinary = function(sData) {
console.log("calling sendAsBinary() method...");
var nBytes = sData.length, ui8Data = new Uint8Array(nBytes);
for(var nIdx = 0; nIdx < nBytes; nIdx++) {
ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff;
}
this.send(ui8Data);
};
}
However, even though I implement the above, I am still getting:
Uncaught TypeError: Object #<XMLHttpRequest> has no method 'sendAsBinary'
In Chrome 30.0.1599.101. I also never see my console.log() message.
It seems that in Chrome you cannot use sendAsBinary but the FormData object and the send method. I assume you want to upload a file:
var file = event.originalEvent.dataTransfer.files[0];
var dashes = '--';
var boundary = 'fuhtml5';
var crlf = '\r\n';
if (file.getAsBinary) { // Firefox
var data = dashes + boundary + crlf +
"Content-Disposition: form-data;" +
"name=\"" + settings.name + "\";" +
"filename=\"" + unescape(encodeURIComponent(file.name)) + "\"" + crlf +
"Content-Type: application/octet-stream" + crlf + crlf +
file.getAsBinary() + crlf +
dashes + boundary + dashes;
xmlHttpRequest.setRequestHeader("Content-Type", "multipart/form-data;boundary=" + boundary);
xmlHttpRequest.sendAsBinary(data);
} else if (window.FormData) { // Chrome
var formData = new FormData();
formData.append(settings.name, file);
xmlHttpRequest.send(formData);
}
This is not tested. It's extracted from the code at https://github.com/MicheleBertoli/jquery-html5-uploader/
Related
I'm using SheetJS to parse out an externally linked excel spreadsheet and create some HTML elements.
Overall, the way that I have it set up is fine, but I noticed that if the excel sheet that I'm referencing has spaces in the header (e.g. - First Name, Last Name, etc.) it won't recognize that and errors out. And I'm not sure how to go about accommodating the spaces in the headers.
Here's what I have:
Excel File Data:
JS:
var url = "https://assets.codepen.io/8689/test2.xlsx";
/* set up XMLHttpRequest */
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = function (e) {
var arraybuffer = oReq.response;
/* convert data to binary string */
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
/* Call XLSX */
var workbook = XLSX.read(bstr, { type: "binary" });
/* DO SOMETHING WITH workbook HERE */
var first_sheet_name = workbook.SheetNames[0];
/* Get worksheet */
var worksheet = workbook.Sheets[first_sheet_name];
var jData = XLSX.utils.sheet_to_json(worksheet, { raw: false });
$.each(jData, function (i, f) {
var el =
"<div class='thing'>" +
"<h2>" +
f.First Name +
" " +
f.Last Name +
"</h2>" +
"<h3>" +
f.Title +
"</h3>" +
"<p>" +
f.Comment +
"</p>" +
"</div>";
$(el).appendTo("#wrapper");
});
console.log(jData);
};
oReq.send();
I know that f.First Name and f.Last Name will error out, and I'm not sure what I can do to try and get it to accommodate the space. I tried an underscore, but that obviously doesn't work either (I kind of figured, but I wanted to test to be sure).
Ok, I did some more digging and I realized that since this is JSON data that is being parsed, I can use bracket notation to help parse that out:
$.each(jData, function (i, f) {
var el =
"<div class='thing'>" +
"<h2>" +
f["First Name"] +
" " +
f["Last Name"] +
"</h2>" +
"<h3>" +
f.Title +
"</h3>" +
"<p>" +
f.Comment +
"</p>" +
"</div>";
});
I am writing a small Cordova (PhoneGap) app. that is sending an image from a file input - using a post method. It works fine in my Android device, but fails in both broswer and Ripple emulator. Here is the code:
function queryImageByData(dataURL) {
var imgType = dataURL.substring(5, dataURL.indexOf(";"));
var imgExt = imgType.split("/")[1];
var imgData = atob(dataURL.substring(dataURL.indexOf(",") + 1));
var filenameTimestamp = (new Date().getTime());
var separator = "----------12345-multipart-boundary-" + filenameTimestamp;
var formData = "--" + separator + "\r\n" +
"Content-Disposition: file; name=\"file\"; filename=\"snapshot_" + filenameTimestamp + "." + imgExt + "\"\r\n" +
"Content-Type: " + imgType + "\r\nContent-Transfer-Encoding: base64" + "\r\n\r\n" + imgData + "\r\n--" + separator + "\r\n";
var xhr = new XMLHttpRequest();
xhr.sendAsBinary = function (data) {
var arrb = new ArrayBuffer(data.length);
var ui8a = new Uint8Array(arrb, 0);
for (var i = 0; i < data.length; i++) {
ui8a[i] = (data.charCodeAt(i) & 0xff);
}
var blob = new Blob([arrb]);
this.send(blob);
};
xhr.open("POST", "https:/my_endpoint_here", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
parseResult(xhr.responseText);
}
else {
onFailedResponse(xhr.responseText);
}
}
};
xhr.setRequestHeader("Content-type", "multipart/form-data; boundary=" + separator);
xhr.sendAsBinary(formData);
}
The error I get is:
Error: MultipartParser.end(): stream ended unexpectedly: state = HEADER_FIELD_START
at MultipartParser.end
EDIT:
I have a problem also with a get method. It fails on Ripple/Browser but runs OK on the device. here is some sample code:
var url = document.getElementById("urlInput").value;
var query = "my_url_here";
var jqxhr = $.ajax(query)
.done(function (data) {
alert("success" + data);
})
.fail(function (data) {
alert("error" + data);
})
Well I found the core issue, which cross domain calls.
The browsers do not allow it, and apperently so does Ripple emulator,
but mobile devices do allow it.
Now I just need to figure out how to make it work using CORS.
please help me my probs,am using kendo ui grid in my webapp & trying to grid data export into EXcel and CSV format. Code Works good in Chrome and files are downloading, but in Fire Fox its open a new window show the grid details in url and says bad request,
//code is
$("#exportcsv").click(function (e) {
debugger
var dataSource = $("#grid").data("kendoGrid").dataSource;
var filteredDataSource = new kendo.data.DataSource({
data: dataSource.data(),
filter: dataSource.filter()
});
filteredDataSource.read();
var data = filteredDataSource.view();
//start with the desired column headers here
var result = "\"ID\",\"EID\",\"Name\",\"Company Name\",\"Salary\",\"DID\",\"Date Of Join\"";
//each column will need to be called using the field name in the data source
for (var i = 0; i < data.length; i++) {
result += "\n";
result += "\"" + data[i].id + "\",";
result += "\"" + data[i].EID + "\",";
result += "\"" + data[i].EName + "\",";
result += "\"" + data[i].CName + "\",";
result += "\"" + data[i].Salary + "\",";
result += "\"" + data[i].DID + "\",";
result += "\"" + data[i].DOJ + "\",";
}
if (window.navigator.msSaveBlob) {
//Internet Explorer
window.navigator.msSaveBlob(new Blob([result]), 'ExportedKendoGrid.csv');
}
else if (window.webkitURL != null) {
//Google Chrome and Mozilla Firefox
var a = document.createElement('a');
result = encodeURIComponent(result);
a.href = 'data:application/csv;charset=UTF-8,' + result;
a.download = 'ExportedKendoGrid.csv';
a.click();
}
else {
//Everything Else
window.open(result);
}
e.preventDefault();
});
//below code is not working in firefox browser else if
(window.webkitURL != null) {
//Google Chrome and Mozilla Firefox
var a = document.createElement('a');
result = encodeURIComponent(result);
a.href = 'data:application/csv;charset=UTF-8,' + result;
a.download = 'ExportedKendoGrid.csv';
a.click();
}
This title may not be 100% accurate with regards to my question, and I apologize beforehand if that's the case. Here's my problem, I found this cool applet that allows you to paste an image from your clipboard without the need for an upload. However, my site does not use explicitly written HTML, so I don't know how to insert this applet. For example, here is my code for an Upload button, the kind you would use normally to input an image:
getUploadControl: function(data) {
var uploadData = data.uploadData || {},
resultHandler = generateCallbackHandler({
success: data.onSuccess,
error: data.onError,
busyMethod: noop
}),
eventHandler = function(e) {
var jsonResponse = parseJSON(e.XMLHttpRequest.responseText);
resultHandler(jsonResponse);
};
return extend(true, {
type: "upload",
options: {
async: {
saveUrl: window.CaledonianAPIWebServiceRoot + "WriteFile.aspx"
},
multiple: false,
upload: function(e) {
var ud = copyNestedProperties({}, uploadData);
api.addAuthToData(ud);
e.data = ud;
},
success: eventHandler,
error: eventHandler
}
}, data);
},
I would like to make a similar button like this using the SUPA Applet. Here is a demo of the applet.
I have downloaded the source code for Supa.js, here it is, not very long.
function Supa() {
this.ping = function (supaApplet) {
try {
// IE will throw an exception if you try to access the method in a
// scalar context, i.e. if( supaApplet.pasteFromClipboard ) ...
return supaApplet.ping();
} catch (e) {
return false;
}
};
this.ajax_post = function (actionUrl, bytes, fieldname_filename, filename, params) {
// some constants for the request body
//FIXME: make sure boundaryString is not part of bytes or the form values
var boundaryString = 'AaB03x' + parseInt(Math.random() * 9999999, 10),
boundary = '--' + boundaryString,
cr = '\r\n',
body,
i,
isAsync,
xrequest;
// sanity checks
if (!fieldname_filename || fieldname_filename === "") {
throw "Developer Error: fieldname_filename not set or empty";
}
if (!filename || filename === "") {
throw "Filename required";
}
// build request body
body = '';
body += boundary + cr;
if (isArray(params)) {
for (i = 0; i < params.length; i += 1) {
body += "Content-disposition: form-data; name=\"" + escape(params[i].name) + "\";" + cr;
body += cr;
body += encodeURI(params[i].value) + cr;
body += boundary + cr;
}
}
// add the screenshot as a file
body += "Content-Disposition: form-data; name=\"" + escape(fieldname_filename) + "\"; filename=\"" + encodeURI(filename) + "\"" + cr;
body += "Content-Type: application/octet-stream" + cr;
body += "Content-Transfer-Encoding: base64" + cr;
body += cr;
body += bytes + cr;
// last boundary, no extra cr here!
body += boundary + "--" + cr;
// finally, the Ajax request
isAsync = false;
xrequest = new XMLHttpRequest();
xrequest.open("POST", actionUrl, isAsync);
// set request headers
xrequest.setRequestHeader("Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + boundaryString);
xrequest.send(body);
return xrequest.responseText;
};
}
function supa() {
return new Supa();
}
My question is how do I make a similar widget to use this library for the pasting process? The paste() method can be found in the source HTML for the demo I referenced earlier, it's not in Supa.js, the main file. Plus, I'm not using HTML, so I might have to combine all that code into one? Anyway, any help is appreciated, to get me going on the right track.
I'm writing a script that stores database backup files to multiple locations. In addition, the data is stored on a NAS, which is normally accessible. If this is not the case, the error message is to be intercepted.
I tried it this way:
wshshell = WScript.CreateObject("WScript.Shell");
fso = WScript.CreateObject("Scripting.FileSystemObject");
SetupPath = WScript.arguments(0);
if (fso.FileExists(SetupPath))
{
//Load setup JSON
SetupFile = fso.OpenTextFile(SetupPath, 1, true, 0);
eval(SetupFile.ReadAll());
// Parse setup configuration from JSON
...
BackupPath = Setup["BackupPath"];
FilesForBackup = Setup["FilesForBackup"];
NASBackupPath = Setup["NASBackupPath"];
...
CreateNewBackupFiles();
Log("Script was successfully executed.");
}
else
{
Log("Script was not successfully executed.");
}
/* Creates a new compressed database backup */
function CreateNewBackupFiles()
{
tempfile = fso.GetTempName();
file = fso.GetFile("C:\\Program\\7-Zip\\7z.exe");
rarexe = file.ShortPath;
script = rarexe + " a -r " + tempfile + " " + FilesForBackup;
wshshell.Run(script, 0, true);
fso.CopyFile(tempfile, BackupPath + PrefixBackupFile + "backup.7z");
//Save to NAS
if(NASBackupPath!="")
{
try
{
fso.CopyFile(tempfile, NASBackupPath);
}
catch(err)
{
Log("Path \"" + NASBackupPath + "\" not available.");
}
}
fso.DeleteFile(tempfile, true); //delete tempfile
}
/* Saves a log in "Debug.Log" */
function Log(msg)
{
fs = WScript.CreateObject("Scripting.FileSystemObject");
a = fs.OpenTextFile("Debug.log", 8, true, 0);
line = "[" + CurrentTime()+ "] ";
line += "[" + WScript.ScriptName + "] ";
line += "[" + msg + "]";
a.WriteLine(line);
}
Nevertheless, errors continue to be issued. I´m using the Script on Windows XP SP3. Is there a possibility to catch this error with javascript?
thanks
I have found the error. The error came from the "Log". First, not every time a new "File System object" must be created. It can be simply used the object "fso". In addition, the open text file must be closed at the end of the function. Here is the correction:
function Log(msg)
{
a = fso.OpenTextFile("Debug.log", 8, true, 0);
line = "[" + CurrentTime()+ "] ";
line += "[" + WScript.ScriptName + "] ";
line += "[" + msg + "]";
a.WriteLine(line);
a.Close();
}