I'm writing an AIR application that communicates with a server via XmlHttpRequest.
The problem that I'm having is that if the server is unreachable, my asynchronous XmlHttpRequest never seems to fail. My onreadystatechange handler detects the OPENED state, but nothing else.
Is there a way to make the XmlHttpRequest time out?
Do I have to do something silly like using setTimeout() to wait a while then abort() if the connection isn't established?
Edit:
Found this, but in my testing, wrapping my xmlhttprequest.send() in a try/catch block or setting a value on xmlhttprequest.timeout (or TimeOut or timeOut) doesn't have any affect.
With AIR, as with XHR elsewhere, you have to set a timer in JavaScript to detect connection timeouts.
var xhReq = createXMLHttpRequest();
xhReq.open("get", "infiniteLoop.phtml", true); // Server stuck in a loop.
var requestTimer = setTimeout(function() {
xhReq.abort();
// Handle timeout situation, e.g. Retry or inform user.
}, MAXIMUM_WAITING_TIME);
xhReq.onreadystatechange = function() {
if (xhReq.readyState != 4) { return; }
clearTimeout(requestTimer);
if (xhReq.status != 200) {
// Handle error, e.g. Display error message on page
return;
}
var serverResponse = xhReq.responseText;
};
Source
XMLHttpRequest timeout and ontimeout is a-syncronic and should be implemented in js client with callbacks :
Example:
function isUrlAvailable(callback, error) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
return callback();
}
else {
setTimeout(function () {
return error();
}, 8000);
}
};
xhttp.open('GET', siteAddress, true);
xhttp.send();
}
Related
I have an xmlhttprequest code that is executed on a button, it runs and access the advReqPage.aspx on the first run but when I press the button again, it doesn't access the advReqPage.aspx any more. What is the problem here?
function SaveAdvPayment() {
var xhr = new XMLHttpRequest();
var ornumber = document.getElementById("ORNumber").value;
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status === 200) {
// OK
alert('response:' + xhr.responseText);
// here you can use the result (cli.responseText)
} else {
// not OK
alert('failure!');
}
}
}
xhr.open("GET", "Server_Requests/advReqPage.aspx?poo=" + ornumber + "&sess=INSERT", false);
xhr.send();
alert('Saved');
$('#myModal').modal('hide');
}
Probably the first response is getting cached and when you make the second request your browser is not making this new request. This behavior is due to browser locking the cache and waiting to see the result of one request before requesting the same resource again. You can overcome this by making your requests unique like adding random query string.
I have this function for sending data to my (localhost) server. However, when Wamp was accidentally stopped (localhost server down) I noticed that timeout is not working properly.
If I set the timeout to 2000 mS, the callback is called normally like is supposed. If I set to 4000 mS, the timeout is never called. Instead, readystate will reach 4 (DONE) but with no meaning HTTP status (zero?).
The debug is as follows:
READY STATE: 2 STATUS: 0
READY STATE: 4 STATUS: 0
This is normal or do I miss something here?
I use Firefox latest, 53. Thanks.
function ServerSend(url) {
var xhr = new XMLHttpRequest();
// In Internet Explorer, the timeout property may be set only after calling the open() method and before calling
// the send() method.
xhr.open("GET", url, true);
xhr.timeout = 4000;
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
ShowInfo(xhr.responseText)
}
// DEBUG
{
console.log("READY STATE: "+xhr.readyState+" STATUS: "+xhr.status);
}
};
xhr.ontimeout = function () {
xhr.abort();
alert("Timed out!!!");
//ShowInfo("Server timeout");
};
xhr.send();
}
I'm trying to send XMLHttpRequest from client side js to my node server. But nothing is happening. I'm quite new to this stuff. This is my function in javascript.
function sendTokenToServer(token) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
// document.getElementById("demo").innerHTML = xhttp.responseText;
console.log(xhttp.responseText);
}
xhttp.open("GET","http://localhost:3000/", true);
xtthp.send();
};
}
And this is my route in node js
app.get('/fcm', function(req, res) {
console.log('here');
res.end('hee');
});
You aren't making a request to the endpoint you created, you are requesting the route: / (which may or may not exist). Change the request to
xhttp.open("GET","http://localhost:3000/fcm", true);
And it should work (assuming your webpage and the server are running on the same port, otherwise you could run into CORS issues).
I have this problem.
I have a function for example called functionA() that needs the results from another function called functionB().
var globalVar="";
function functionA(){
//...
functionB();
//here i have to use the global variable (that is empty because functionB isn't finished)
}
function functionB(){
//ajax request
globalVar=ajaxRequest.responseText;
}
How can I do to let the functionB finish befor continue with the execution of functionA?
Thanks!
This is the code:
var ingredientiEsistenti="";
function ShowInserisciCommerciale() {
getElementiEsistenti();
JSON.parse(ingredientiEsistenti);
}
function getElementiEsistenti(){
// prendo gli ingredienti esistenti.
var url = "http://127.0.0.1:8080/Tesi/Ingredienti";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", url, false);
xmlHttp.send(null);
xmlHttp.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) // COMPLETED
{
if (xmlHttp.status == 200) // SUCCESSFUL
{
ingredientiEsistenti = xmlHttp.responseText;
} else {
alert("An error occurred while communicating with login server.");
}
}
};
}
You've got one of many options, that don't require an evil global variable:
Move the code you want to see executed to the onreadystatechange callback of the ajax request, that way, it won't get executed until you received a response
Redefine functionA, so that it takes a parameter that allows you to skip the first bit:
Make the request synchronous, not recommended, though
use a timeout/interval to check the readystate of the request manually (brute-force, not recommended either)
Perhaps there is some worker trickery that could do the trick, too, in your particular case
function functionA(skipDown)
{
skipDown = skipDown || false;
if (skipDown === false)
{
//doStuff
return functionB();//<-- call functionA(true); from the readystatechange callback
}
//this code will only be called if skipDown was passed
}
It is impossible to have a sleep/wait in JavaScript when the call is asynchronous. You need to use a callback pattern to make this action occur.
It is possible to make an XMLHttpRequest synchronous, but that can lead to other problems. It can hang the browser as it blocks all other actions from happening. So if you want to show a loading animation, it most likely will not execute.
You can make your AJAX request synchronous. https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
var request = new XMLHttpRequest();
// Last parameter makes it not asnychronous
request.open('GET', 'http://www.mozilla.org/', false);
request.send(null);
// Won't get here until the network call finishes
if (request.status === 200) {
console.log(request.responseText);
}
However, that will block the UI while waiting for the server to respond, which is almost never what you want. In that case, you should use a callback to process results.
Here's an example using a callback without relying on a global variable. You should always run away from those
function ShowInserisciCommerciale( ) {
getElementiEsistenti(function(responseText) {
JSON.parse(responseText);
});
}
function getElementiEsistenti(successCallback){
var url = "http://127.0.0.1:8080/Tesi/Ingredienti";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", url, false);
xmlHttp.send(null);
xmlHttp.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) // COMPLETED
{
if (xmlHttp.status == 200) // SUCCESSFUL
{
successCallback(xmlHttp.responseText);
} else {
alert("An error occurred while communicating with login server.");
}
}
};
}
I'm looking on the web, but documentation is hard to come by. We all know the basic AJAX call using the browser's built-in XMLHttpRequest object (assume a modern browser here):
var xmlHttp = new XMLHttpRequest(); // Assumes native object
xmlHttp.open("GET", "http://www.example.com", false);
xmlHttp.send("");
var statusCode = xmlHttp.status;
// Process it, and I'd love to know if the request timed out
So, is there a way that I can detect that the AJAX call timed out by inspecting the XMLHttpRequest object in the browser? Would I be advised to do something like window.setTimeout(function() { xmlHttp.abort() }, 30000);?
Thanks!
-Mike
Some of the modern browsers (2012) do this without having to rely on setTimeout: it's included in the XMLHttpRequest. See answer https://stackoverflow.com/a/4958782/698168:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert("ready state = 4");
}
};
xhr.open("POST", "http://www.service.org/myService.svc/Method", true);
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.timeout = 4000;
xhr.ontimeout = function () { alert("Timed out!!!"); }
xhr.send(json);
UPDATE: Here's an example of how you can handle a timeout:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://www.example.com", true);
xmlHttp.onreadystatechange=function(){
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
clearTimeout(xmlHttpTimeout);
alert(xmlHttp.responseText);
}
}
// Now that we're ready to handle the response, we can make the request
xmlHttp.send("");
// Timeout to abort in 5 seconds
var xmlHttpTimeout=setTimeout(ajaxTimeout,5000);
function ajaxTimeout(){
xmlHttp.abort();
alert("Request timed out");
}
In IE8, You can add a timeout event handler to the XMLHttpRequest object.
var xmlHttp = new XMLHttpRequest();
xmlHttp.ontimeout = function(){
alert("request timed out");
}
I would recommend against making synchronous calls as your code implies and also recommend using a javascript framework to do this. jQuery is the most popular one. It makes your code more efficient, easier to maintain and cross-browser compatible.