Create an HTTP request after btoa() is complete in javascript - javascript

I am trying to send a file as a base64 string to a server. The server requires that the data is sent as an HTTP 'POST' with the information is JSON. However, in my code, the request is sent before the string is converted. Please advise on what error I am making in my code.
This is the function which converts the file
function handleFileSelect(evt) {
var files = evt.files;
var file = files[0];
var string = '';
if (files && file)
{
var reader = new FileReader();
reader.onload = function(readerEvt)
{
var binaryString = readerEvt.target.result;
string = btoa(binaryString);
};
reader.readAsBinaryString(file);
}
create_HTTP_request(string);};
This is my HTTP request function(s)
function create_HTTP_request(string)
{
runTask('task_required_by_server', {'file' : string}, format_data);
};
function runTask(task_name, inputs, callback){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('Request Successful!');
callback(xmlhttp.responseText);
console.log(xmlhttp.responseText);
}
else if(xmlhttp.readyState == 4 && xmlhttp.status == 500)
{
console.log(xmlhttp.responseText);
}
else {
console.log(xmlhttp.responseText);
}
}
xmlhttp.open("POST", '/api/v1/jobs', true);
xmlhttp.setRequestHeader('Content-Type', 'application/json');
xmlhttp.send(JSON.stringify({name: task_name, input: inputs}));
};
I am new to Javascript. I basically want to call my create_HTTP_request function only after the btoa() function is complete. Thanks for your time!

Related

Safari 10 on Mac not uploading file in XHR

I'm using XHR to upload an image to an external server which has CORS enabled.
everything works fine in Chrome, Firefox and IE.
But using Safari, server response with mime type error. saying the file type is 'application/octet-stream' while it should be 'image/*'.
After I disabled mime type checking, safari can upload file but its all 0b empty file.
anyone knows why?
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://up-z1.qiniu.com/', true);
var formData;
formData = new FormData();
formData.append('key', file.name);
formData.append('token', acessToken);
formData.append('file', file);
xhr.onreadystatechange = function (response) {
if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText != "") {
callback(true,null);
} else if (xhr.status != 200 && xhr.responseText) {
callback(false,null);
}
};
xhr.send(formData);
So according to another stackoverflow question, I cant remember which one
Safari has a bug that when other browsers do file.toBlob(), safari will do file.toString(). So the workaround would be write your own file to blob function and upload that blob.
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://up-z1.qiniu.com/', true);
var formData;
formData = new FormData();
formData.append('key', file.name);
formData.append('token', acessToken);
formData.append('file', fileToBlob(file));
xhr.onreadystatechange = function (response) {
if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText != "") {
callback(true,null);
} else if (xhr.status != 200 && xhr.responseText) {
callback(false,null);
}
};
xhr.send(formData);
This is a very weird one. I came to the same conclusion as +arslan2012 .
For anyone stuck on the fileToBlob function he refers to, here's what I am using
const readFileContents = function(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = function(evt) {
resolve(evt.target.result)
};
reader.onerror = function() {
reader.abort()
reject(new DOMException("Unable to read the file."))
}
reader.readAsArrayBuffer(file);
})
}

Get JSON from local JavaScript

good afternoon. I'm developing an app that can get a JSON from local (manifest.json). I want to get this file from JavaScript and then read it. But I have a problem, I cant call this file. How can I?
var urlJSON = new XMLHttpRequest("manifes.json").toString;
var dataJSON = JSON.parse(urlJSON);
alert(dataJSON.name);
var xmlhttp = new XMLHttpRequest();
var url = 'manifest.json';
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log(JSON.parse(xmlhttp.responseText));
}
if (xmlhttp.status == 404) {}
};
xmlhttp.open('GET', url, true);
xmlhttp.send();
Or run chrome with arguments --allow-file-access-from-files
Or download and create server for your app

How to validate the existence of a JSON file before load it with the XMLHttpRequest Javascript object?

I am working loading a JSON file from a relative local path into my web based app. To do this I am using an XMLHttpRequest object, as following:
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'myFyle.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(JSON.parse(xobj.responseText));
}
}
xobj.send(null);
My issue is that I can't manage the browser error (net::ERR_FILE_NOT_FOUND) when myFyle.json is not found. I would like to load an standard .json file (e.g. myStandardFile.json) when this happens.
Does anybody has an idea to do this?
Thanks in advance!
Pedro.
You can use xobj.status === 404 to detect 'file not found'.
The web site hosting server will typically generate a "404 Not Found"
web page when a user attempts to follow a broken or dead link;
In case of 404 you can load your default file like this:
function load(file, callback) {
var defaultFile = "myStandardFile.json";
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', file, true);
xobj.onreadystatechange = function() {
if (xobj.readyState !== 4) return true;
if (xobj.status === 200) {
callback(JSON.parse(xobj.responseText));
//File not found.
//The second condition just to prevent endless calls
//in case if your default file doesn't exist
} else if (xobj.status === 404 && file !== defaultFile) {
load(defaultFile, callback);
}
}
xobj.send(null);
}
load("myFyle.json", function(data) {
console.log(data);
})
Demo:
function load(file, callback) {
var defaultFile = "https://httpbin.org/user-agent";
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', file, true);
xobj.onreadystatechange = function() {
if (xobj.readyState !== 4) return true;
if (xobj.status === 200) {
callback(JSON.parse(xobj.responseText));
//File not found
} else if (xobj.status === 404 && file !== defaultFile) {
load(defaultFile, callback);
}
}
xobj.send(null);
}
load("https://httpbin.org/inexistentFile.json", function(data) {
console.log(data);
})
I hope this will help you.

How to pass a JSON object using form data to a rest service using JS

I have a rest webservice which can accept a string. I want to pass a json object as a string to this service. I have to use a HTML page with some textfields and has to pass the form data to the service. can any one help??
Thankyou
you can try this
function callWebService{
var field= document.getElementById('field').value;
//use jquery to convert to json object
//see comment for more info on this
var ws = 'http://localhost:8080/WebServicePath/';
var url = ws + field;
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert("Success");
}
else {
alert("Failure");
}
};
xmlhttp.open('GET', url, true);
xmlhttp.send(null);
}

How to download and then upload the file?

Tried to use the following code, but it doesn't work properly:
// download the file first
var req = new XMLHttpRequest();
req.open('GET', url, false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
// upload the file
req.open("POST", "http://mysite.com/upload", false);
req.setRequestHeader("Content-Length", req.responseText.length);
req.sendAsBinary(req.responseText); // What should I pass here?
if (req.status != 200) return '';
return req.responseText;
sendAsBinary is firefox function.
Upd. Also I've tried to upload that as part of the form:
var response = req.responseText;
var formData = new FormData();
formData.append("file", response);
req.open("POST", "http://mysite.com/upload", false);
req.send(formData);
But still not full data is received by the server.
Finally I've used the approach with temp file:
var downloadCompleted = false;
// download the file first
var persist = Components.classes["#mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Components.interfaces.nsIWebBrowserPersist);
// get OS temp folder
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
file.append("temp.ext");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
var fURI = Services.io.newURI(url,null,null);
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
persist.progressListener = {
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
},
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
downloadCompleted = true; // file has been downloaded
}
}
}
persist.saveURI(fURI, null, null, null, "", file);
var thread = Components.classes["#mozilla.org/thread-manager;1"]
.getService(Components.interfaces.nsIThreadManager)
.currentThread;
while (!downloadCompleted) // emulate synchronous request, not recommended approach
thread.processNextEvent(true);
// upload the file
var stream = Components.classes["#mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance
// try to determine the MIME type of the file
var mimeType = "text/plain";
try {
var mimeService = Components.classes["#mozilla.org/mime;1"]
.getService(Components.interfaces.nsIMIMEService);
mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
}
catch(e) { /* just use text/plain */ }
var req = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
req.open('POST', "http://mysite.com/upload", false);
req.setRequestHeader('Content-Type', mimeType);
req.send(stream);
// delete the file
file.remove(false);
You need to store the responseText in an intermediate variable before reusing the req object.
// download the file first
var req = new XMLHttpRequest();
req.open('GET', url, false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var response = req.responseText;
// upload the file
req.open("POST", "http://mysite.com/upload", false);
req.setRequestHeader("Content-Length", response.length);
req.sendAsBinary(response);
if (req.status != 200) return '';
return req.responseText;
Update
Per the MDN page Using XMLHttpRequest, it looks like the above code won't work. Following is the proper way to get the binary response. In the end, you will have an array of unsigned integers which you could send back to the server and convert to binary. I think.
//req.responseType is only defined for FF6+
req.responseType = "arraybuffer";
req.send(null);
//req.response is for FF6+, req.mozResponseArrayBuffer is for FF < 6
var buffer = req.mozResponseArrayBuffer || req.response;
if (buffer) {
var byteArray = new Uint8Array(buffer);
}
Update 2
To submit the byteArray to a server, I would try something like the following untested, almost guaranteed not to work code.
req.open("POST", "http://mysite.com/upload", false);
req.setRequestHeader("Content-Length", byteArray.length);
//if this doesn't work, try byteArray.buffer
//if byteArray.buffer works, try skipping 'var byteArray = new Uint8Array(buffer);' altogether and just sending the buffer directly
req.send(byteArray);
Update 3
Could Using XMLHttpRequest from JavaScript modules / XPCOM components have anything to do with your issue?

Categories

Resources