XMLHttpRequest that is being Aborted - javascript

I'm looking over a bit of code that deals with XHR. It looks like the first XHR.send() is being done successfully and then the subsequent one is Aborted before it gets to it's .send()
Quick in dirty:
url = "http://192.168.1.1/cgi-bin/test.cgi";
data = "1235,123,21,1232,12321,432";
myXHR = new Array();
for(var i = 0; i < 2; i++) {
myXHR[i] = new XMLHttpRequest();
myXHR[i].open("POST", url, true);
myXHR[i].onerror = function() {
alert("Error occurred");
};
myXHR[i].onload = function() {
if(myXHR[i].status == 200) {
alert("Yay I worked");
var data = myXHR[i].responseText;
}
};
// do some setting up of XHR headers
myXHR[i].send(data);
myXHR[i] = null;
}
What could be happening that would cause Firebug to show Abort before the second .send() is done?

Try this:
url = "http://192.168.1.1/cgi-bin/test.cgi";
data = "1235,123,21,1232,12321,432";
var myXHR = [];
for(var i = 0; i < 2; i++) {
myXHR[i] = new XMLHttpRequest();
myXHR[i].open("POST", url, true);
myXHR[i].onerror = function() {
alert("Error occurred");
};
myXHR[i].onload = function() {
if(myXHR[i].status == 200) {
alert("Yay I worked");
var data = myXHR[i].responseText;
}
};
// do some setting up of XHR headers
myXHR[i].send(data);
myXHR[i] = null;
}

When I run this code I get TypeError: myXHR[i] is undefined (on the stock firefox 20 install on my mac... what version are you on)?
At any rate, I can see one issue with this (i.e. myXHR[i] will be undefined...) that might also apply to you, in particular with:
myXHR[i].onload = function() {
if(myXHR[i].status == 200) {
alert("Yay I worked");
var data = myXHR[i].responseText;
}
};
Because this is triggered asynchronously i will have been incremented to 2, which is of course going to be outside the bounds of the two element myXHR array. Have you tried closing over the value of i, like so:
myXHR[i].onload = (function(i) {
return function() {
if(myXHR[i].status == 200) {
alert("Yay I worked");
var data = myXHR[i].responseText;
}
}
})(i);
Because once I correctly save that i value in that function body this code will succeed for both calls.
I know this isn't the exact issue you're having, but I think it will be an issue regardless so you may as well give it a go right? It's not as though there have been a huge number of other answers unfortunately.
hope this helps..

Found out what was happening.
The XHR was being aborted because there was no return value from the webserver that the request was being sent to. The web server is a custom based one that we seem to be using the someone changed the code so that it wasn't sending a 200 Success OK even if the data sent to it had no data coming back.
All good now. Thanks for the help.

Related

Creating global VAR in functions

So I'm having trouble with getting a VAR in a function to be global, I have tried the following resources:
What is the scope of variables in JavaScript?
My previous question was marked as a duplicate but after reviewing the link above it did not help with my issue.
Here is my previous question:
So I'm using OpenTok to create a online conferencing tool and need to grab the session details from an API on a different server. I've created a php script on the other server that grabs session information based on the session id provided by a URL parameter. I know that the php script and most of the JavaScript is working correctly because when I console.log data from the parsed JSON it prints the correct information. However when I try to put the variables into the credentials area I get the following error:
ReferenceError: thesession is not defined
Here is the code used to get the JSON from a PHP script on a separate server:
var url_string = window.location.href;
var url = new URL(url_string);
var session = url.searchParams.get("s");
if (session == '') {
window.location.replace("http://www.google.com");
}
var getJSON = function(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status === 200) {
callback(null, xhr.response);
} else {
callback(status, xhr.response);
}
};
xhr.send();
};
getJSON('http://192.168.64.2/api/meeting/?uid=' + session,
function(err, data) {
if (err !== null) {
console.log('Error');
}
var thesession = data.sessionID;
var thetoken = data.token;
console.log(thesession);
console.log(thetoken);
});
let otCore;
const options = {
credentials: {
apiKey: "####",
sessionId: thesession,
token: thetoken
},
And here is a screenshot of the console:
The top console log is "thesession" and the second console log is "thetoken". I have tried looking up the error but can't quite find one with the same usage as mine.
The desired outcome would be that I could using the data from the parsed JSON and use the result as the credentials e.g. data.sessionID which is bound the the VAR thesession.
I know this might be a scope issue, but I'm not sure how I could alter the code to make it work as intended.
Any help would be much appreciated, this one has really got me stumped :)
How would I alter the scope to get the desired function? I have reviewed the link that was given on the previous question, but this didn't help me with my issue.
var thesession = data.sessionID;
Is defined within its execution context, which is the callback function you've passed to getJSON.
One step in the right direction is to reverse the assignment. Assign 'thesession' to the options object within the scope where 'thesession' exists.
const options = {
credentials: {
apiKey: "####",
sessionId: null,
token: thetoken
}
};
getJSON('http://192.168.64.2/api/meeting/?uid=' + session,
function(err, data) {
if (err !== null) {
console.log('Error');
}
var thesession = data.sessionID;
var thetoken = data.token;
console.log(thesession);
console.log(thetoken);
options.credentials.sessionId = thesession;
});
However, it's important to realize that your program is not going to wait for this assignment. It will send the getJSON request, and then continue processing. Your options object won't have a sessionId until the getJSON call finishes and its callback has been invoked.
This would be a good opportunity to delve into Promises, which will help you better understand how to handle the non-blocking nature of javascript.
Your problem is that this line var thesession = data.sessionID is scoped within the function function(err, data) { ... }. In order to allow two functions to use the same variable, you need to make sure that the variable isn't declared somewhere they don't have access to.
It's the difference between this:
function func1() {
var x = 3
}
function func2() {
console.log(x)
}
func1();
func2();
and this:
var x;
function func1() {
x = 3
}
function func2() {
console.log(x)
}
func1();
func2();
Similarly, if you declare var thesession; at the start of your script (or at least outside that other function) then just set it with thesession = data.sessionID, your final part will have access to your variable thesession.
Edit
In context:
var url_string = window.location.href;
var url = new URL(url_string);
var session = url.searchParams.get("s");
var thesession;
var thetoken;
if (session == '') {
window.location.replace("http://www.google.com");
}
var getJSON = function(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status === 200) {
callback(null, xhr.response);
} else {
callback(status, xhr.response);
}
};
xhr.send();
};
getJSON('http://192.168.64.2/api/meeting/?uid=' + session,
function(err, data) {
if (err !== null) {
console.log('Error');
}
thesession = data.sessionID;
thetoken = data.token;
console.log(thesession);
console.log(thetoken);
});
let otCore;
const options = {
credentials: {
apiKey: "####",
sessionId: thesession,
token: thetoken
},
As a side-note - I'd also recommend not using var and instead just using let of const, depending on if you want your variable to be mutable or not.

Trying to post to a .txt file fails but performing a get does work

My partner and I are trying to get a domain that I own, communicate with a ios app that is run on objective c to work via http. He is using the code that was provided by this link Sending an HTTP POST request on iOS.
He is able to do a GET to receive the data in my .txt page but when he performs a PUT to try and write to that file so that I can get that data it fails. We are both rather new to http so it is possible that we are missing something. A concern we have is that he doesn't have the privileges to write to this file. Any advice would help, thanks!
Here is the javascript I am using on my side. I added a header to my response to try and resolve the cors issue.
(function () {
window.onload = function () {
httpGetAsync("http://students.washington.edu/bharatis/distances.txt", processData)
//alert("hello inside onload");
document.getElementById("first").innerHTML = leader1;
document.getElementById("second").innerHTML = leader1;
document.getElementById("third").innerHTML = leader1;
//window.onbeforeunload = update;
}
function processData(responseText) {
//alert(responseText);
var txt = "";
var x = responseText.getElementsByTagName('Distance'); // Talk to alex about
for(i = 0; i < x.length; i++) {
txt += x[i].childNodes[0].nodeValue;
}
var result = parseDouble(txt);
alert(result);
}
function httpGetAsync(theUrl, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.setRequestHeader("Access-Control-Allow-Origin", "*");
xmlHttp.send("response message");
}
})();

What is different about xmlhttprequest in Firefox

My code works in Chrome and Safari, but it hangs in FF.
I removed the parts of the code that aren't necessary.
I used console commands to show how far the first loop gets, and it will do the second log fine right before the xhr open and send commands.
If the open/send commands are present the loop only happens once, if I remove the open/send commands the loop completes successfully.
Currently using FF 62nightly, but this issue has plagued me since Quantum has come out and I'm now trying to figure out why it doesn't work right.
for (i = 0; i < length; i++) {
(function(i) {
// new XMLHttpRequest
xhr[i] = new XMLHttpRequest();
// gets machine url from href tag
url = rows[i].getElementsByTagName("td")[0].getElementsByTagName('a')[0].getAttribute('href');
// Insert the desired values at the end of each row;
// will try to make this customizable later as well
insertVNC[i] = rows[i].insertCell(-1);
insertSerial[i] = rows[i].insertCell(-1);
insertVersion[i] = rows[i].insertCell(-1);
insertFreeDiskSpace[i] = rows[i].insertCell(-1);
// the fun part: this function takes each url, loads it in the background,
// retrieves the values needed, and then discards the page once the function is complete;
// In theory you could add whatever you want without taking significantly longer
// as long as it's on this page
console.log(i);
xhr[i].onreadystatechange = function() {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
}
};
//"Get" the "Url"... true means asyncrhonous
console.log(url);
xhr[i].open("GET", url, true);
xhr[i].send(null);
})(i); //end for loop
}
I cannot tell you why it gives issues in Firefox. I would not trust sending off arbitrarily many requests from any browser
I would personally try this instead since it will not fire off the next one until one is finished
const urls = [...document.querySelectorAll("tr>td:nth-child(0) a")].map(x => x.href);
let cnt=0;
function getUrl() {
console.log(urls[cnt]);
xhr[i].open("GET", urls[cnt], true);
xhr[i].send(null);
}
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
if (cnt>urls.length) getUrl();
cnt++;
}
}
getUrl();

JSON send not being accepted by server API

I am trying to send a JSON object to a web api, but am having a bit of trouble. Its supposed to take value from an input, check the response first, and if the response is correct, send the data. Here is my JS code:
var form = document.getElementById("inputForm"), master = {}, xhr = new XMLHttpRequest(); //global variables used for checking different parts of the process
form.onsubmit = function (e) {
// stop the regular form submission
e.preventDefault();
// collect the form data while iterating over the inputs
var data = {};
for (var i = 0, ii = form.length; i < ii; ++i) {
var input = form[i];
if (input.name) {
data[input.name] = input.value;
}
master.data = data;
}
// construct an HTTP request
function get(url, callback) {
xhr.open("GET", url);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var type = xhr.getResponseHeader("Content-Type");
if (type.indexOf("xml") !== -1 && xhr.responseXML)
callback(xhr.responseXML);
else if (type === "application/json")
callback(JSON.parse(xhr.responseText));
else
callback(xhr.responseText);
}
};
// send the collected data as JSON
console.log(JSON.stringify(master));
xhr.send(JSON.stringify(master));
}
get("http://example.com:12321/data");
};
However, when sending it, I get a HTTP 500 error in the console, and the output in the server itself says:
Processing request on /data
Caught error: <unspecified file>(1): expected object or array
And here is the result of the console.log:
{"data":{"val":"2"}}
I thought I was sending the data correctly, but it isnt recognizing it. The example they gave was of a .json file and that works fine, but my stringified JSON isnt working.
Any help would be greatly appreciated

Javascript Auto-fresh XMLHttpRequest problem

I'm writing a desktop gadget which should refresh every 10 minutes or so (It's ten seconds here). What I've determined is that every time I execute the setTimeout, the XML doesn't load again.
I don't know what kind of problem this is. I made sure that the objects are set to null, but they don't re-initialize and I'm left with a blank XML object.
setTimeout("bg_load();getXML()",10000);
function getXML()
{
stat = readSetting();
url = "http://www.weather.gov/xml/current_obs/" + stat[0] + ".xml"
rssObj = new XMLHttpRequest();
rssObj.open("GET", url, false);
rssObj.onreadystatechange = function() {
if (rssObj.readyState === 4) {
if (rssObj.status === 200) {
document.getElementById("gadgetContent").innerHTML = "";
rssXML = rssObj.responseXML;
} else {
var chkConn;
document.getElementById("gadgetContent").innerHTML = "Unable to connect...";
}
} else {
document.getElementById("gadgetContent").innerHTML = "Connecting...";
}
}
rssObj.send(null);
getImage(rssXML);
getText(rssXML);
rssObj = null; rssXML = null;
}
With SJAX (Synchronous Ajax), you shouldn't use 'onreadystatechange', and in the code, you pull the response text directly out of the XMLHttpRequest after sending.
Don't Use onreadystatechange:
https://developer.mozilla.org/en/xmlhttprequest#onreadystatechange
Example of pulling the responseText out: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX

Categories

Resources