I'm developing chat app using the long polling technique for real time updates, but after a few minutes of "polling" a request I get the following error:
net::ERR_EMPTY_RESPONSE
As I read , this is expected if the requests waits too long then after a while it responses an empty response , Now I would like to be noticed when such a thing happens ,so I can resend another request to the server.
here is my code :
client.js:
function httpMsgRequest(counter,callback){
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4) { // request is done
if (httpRequest.status === 200) { // successfully
callback(httpRequest.responseText); // we're calling our method
}
}
};
httpRequest.open('GET', "http://localhost:8080/messages?counter=" + counter);
httpRequest.send();
}
function msgPoll() {
try{
httpMsgRequest(counter,function(res){
//callback body
msgPoll();
});
}catch{
msgPoll();
}
}
msgPoll();
I tried to add the try-catch like above but it did not solve the problem. Any one has some idea and can help? Thanks in advance.
Related
So we have this HTTP request call in our rails project which is working good, everything is fine. it calls the controller method and returns the value from that controller (in this case is going to be "true" or "false")
var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
if (!httpRequest) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
httpRequest.open('GET', url);
httpRequest.withCredentials = true;
httpRequest.responseType = 'text';
// httpRequest.setRequestHeader('Content-type', 'application/json');
httpRequest.onreadystatechange = function(){
$container.find('h4').html(JSON.stringify("Error"));
if (httpRequest.readyState === 4) {
$container.find('h4').html(JSON.stringify(httpRequest.response));
// $container.find('h4').html(JSON.stringify("SUCCESS"));
}
};
httpRequest.send();
Now, we want to export this to pdf, with the gem wicked-pdf. After struggling with this, since Wicked PDF converts the JavaScript to some local files and we had problems calling the controller method, because of the CORS, now we successfully call the controller method having a cookie. So, the method is called, but, responseText is empty when in normal conditions as I said at the beginning, it is not since it's building the HTML correctly.
So, the request is okay, is getting to the controller method, and is doing everything, but apparently this is not working:
render :json => #status, :layout => false
and I don't know why I've searched a lot about this and I'm kind of stuck. Why this is working in the normal project, but when trying to execute all this from local files, it doesn't, although is not giving any errors, the logs from rails are this:
INFO -- : Started GET "/monitor/devicestatus_alarms/30" for ::1 at 2020-01-24 09:22:18 +0000
INFO -- : Processing by MonitorController#devicestatus_alarms as JSON
INFO -- : Parameters: {"id"=>"30"}
INFO -- : Completed 200 OK in 45ms (Views: 0.2ms | ActiveRecord: 18.3ms)
I tried to increment the javascript-delay because maybe it required more time to do the calculations in the controller but nothing. responseText is still empty.
Also, we were checking for HTTP status == 200, but then we found out that with local files, when it succeeds, it always returns a status 4, which is returning, so apparently there are no errors. So, how can this request access the controller method, do everything and return with nothing?
Have you tried using AJAX calls to get this job done?
$.ajax({
url: "<your_url>",
type: 'GET',
dataType: 'text',
crossDomain: true,
xhrFields: {
withCredentials: true
}
}).then(function (data) {
< actions here >
}
}).always(function () {
< always action here>
});
"use strict";
(function() {
var url = "http://api.openweathermap.org/data/2.5/weather?q=London,England";
var apiKey = "OMMITTED FOR PRIVACY REASONS"; // Replace "APIKEY" with your own API key; otherwise, your HTTP request will not work
var httpRequest;
makeRequest();
// create and send an XHR request
function makeRequest() {
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = responseMethod;
httpRequest.open('GET', url + '&appid=' + apiKey);
httpRequest.send();
}
// handle XHR response
function responseMethod() {
if (httpRequest.readyState === 4) {
console.log(httpRequest.responseText);
}
}
})();
See link below for a screenshot of the errors, but here's what I'm getting:
An Uncaught ReferenceError on line 12 where my onreadystatechange is.
I also get an error saying 'responseMethod' isn't defined at
makeRequest nor when I call it.
Also getting an error on the very last line for some reason.
Your code looks good. I just replaced your code with my api key and everything worked (see below).
Can you be more specific about the browser where you get an error?
I tried in the latest chrome and firefox and there is no problem.
"use strict";
(function() {
var url = "http://api.openweathermap.org/data/2.5/weather?q=London,England";
var apiKey = "4ff5002c91520701ec111b6082de9387"; // This key might expire soon.
var httpRequest;
makeRequest();
// create and send an XHR request
function makeRequest() {
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = responseMethod;
httpRequest.open('GET', url + '&appid=' + apiKey);
httpRequest.send();
}
// handle XHR response
function responseMethod() {
if (httpRequest.readyState === 4) {
console.log(httpRequest.responseText);
}
}
})();
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 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 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();
}