I’m trying to create a worker that does the following simultaneously:
Sends an XMLHTTPRequest to a server to perform a task (which may
take a long time)
Sends an XML HTTP Request Message every X seconds to get an update on the process until the process (1) is complete.
What i have so far is below. But it doesnt poll. The first part is successfully executed. The second bit runs just once. Does anyone know what i'm doing wrong?
onmessage = function (e) {
e.data.params.task = "runTask"; // The server understands this. This performs(1)
// Sends an asynchronous request to perform (1)
var xhr = new XMLHttpRequest();
xhr.open('POST', e.data.url, false);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(e.data.params));
// initialise polling
var interval = 500;
// Poll until (1) is complete
(function poll(){
if (xhr.readyState != 4){ // while (1) is yet to be completed..
e.data.params.task = "getProgress";
// Send another request to the server to get an update on the first process
var pollxhr = new XMLHttpRequest();
pollxhr.open('POST', e.data.url, true);
pollxhr.setRequestHeader("Content-type", "application/json");
pollxhr.timeout = interval;
pollxhr.ontimeout = poll; // This should cause the process to poll
pollxhr.onreadystatechange = function(){
e.data.progress = pollxhr.responseText;
postMessage(e.data);
};
pollxhr.send(JSON.stringify(e.data.params));
}else{
e.data = xhr.responseText;
postMessage(e.data);
}
})();
};
The problem is with the first call
xhr.open('POST', e.data.url, false);
^^^^^
Looking at the method you can see the third parameter is async
open(DOMString method, DOMString url, optional boolean async, optional DOMString? user, optional DOMString? password);
By setting it to false, you are telling it to run synchronously, which means nothing else will happen until it the call is returned. That results in your polling code running after the first call is returned. Set it to run asynchronously and use the onreadystatechange to get when it is completed!
Related
What my purpose is below
Visting a web and the js.file in this web will load php file, and it will return data to html.
It's meaning every time when I reload web, I will get newest data.
I have try this in js.file
let XML = new XMLHttpRequest();
XML.open('post', url, true);
XML.send('mydata');
then use responseText to get data I want
Indeed, I don't need send any data.
I can do what I want to do, but I am not sure this way is right or not.
Because I think ajax should not use in this case, it must be send something and return something.
What you are saying is you only want to get data without sending anything which is called a http get request, you can do that as below.
function get(url)
{
var xm = new XMLHttpRequest();
// false for synchronous
xm.open("GET",url,false);
xm.send(null);
return xm.responseText;
}
console.log(get('your Url'));
You need to specify the url of your Http Endpoint ( Back-End ).
If your are making a asynchronous request then below code works,,
function get(theUrl, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
// true for asynchronous
xmlHttp.open("GET", theUrl, true);
xmlHttp.send(null);
}
get('your url',(responseText)=>{
console.log(responsetext);
});
Can somebody please explain me when error and ehen timeout error will be raised.
I put timeout here for PUT request but in what use case will be called onTimeout and in what onError handlers?
return new Promise(async function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("PUT", url);
xhr.timeout = 10000;
xhr.onreadystatechange = async function() {
....
}
xhr.ontimeout = function() {
// Time out.
};
xhr.onerror = function() {
// Some error
};
}
The XMLHttpRequest.timeout property is an unsigned long representing the number of milliseconds a request can take before automatically being terminated. The default value is 0, which means there is no timeout. Timeout shouldn't be used for synchronous XMLHttpRequests requests used in a document environment or it will throw an InvalidAccessError exception. When a timeout happens, a timeout event is fired.
Despite the request timeout onerror method fires right after server has sent the error response. For example, if your server is shut down your timeout method will be fired after 10 seconds.
More info: here
I am using below code to capture response but unable to get, please let me know what I am missing here.
function testcall() {
var request = new XMLHttpRequest();
request.open('GET', 'http://demo8951713.mockable.io/fusionchart', true);
request.send();
var response = this.responseText;
alert(response);
}
testcall()
You have two problems.
First, this (in the context you are using it) does not refer to your XHR object.
Second, you are trying to read the response as soon as the request has been sent. You have to wait until the browser has received the response!
request.addEventListener("load", function () {
var response = this.responseText;
alert(response);
});
That change (moving the code to an event handler) also puts this in a context where it refers to the correct object.
Once you have fixed this, you are likely to want to try to return the value. Before you do, read this question.
you are missing the callback function
request.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.response);
}
}
for more details, refer https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response#Example
I am coding a native JavaScript application in which I make simultaneous AJAX requests to multiple unique servers every minute. When a server is offline, I intended my program to handle this through the function registered to the XHR.ontimeout event.
Below is a quick JS sample I wrote to demonstrate my problem. Monitor the console and you will see only sometimes requests to an offline address trigger the ontimeout event. Other times ERR_CONNECTION_TIMED_OUT occurs. I would like to have a timeout handler that executes every time I call my function and the server is offline.
<!DOCTYPE html>
<html>
<TITLE>Timeout Error Demo</TITLE>
<body>
<script>
var i=0;
var xhr;
function main(){
console.log('Main run #'+i);
i++;
xhr=new XMLHttpRequest();
xhr.open("GET", "http://1.1.1.1", true); //this address is always offline
xhr.timeout=2000;
xhr.ontimeout=function(){
console.log("timed out");
}
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200){
console.log("done");
}
}
xhr.send(null);
setTimeout(main,5000);
}
main();
</script>
</body>
</html>
As i see it the core of the problem here is that you misunderstand how the ontimeout event works. So i will try to explain how the browser works with ontimeout and what the difference is with onerror.
ontimeout
The ontimeout event will to thrown when a request is made to the server and that request get succesfully through to the server. Then if the server takes a long time to response the timeout event will get thrown by the HTTPRequest.
Ex:
Client side
xhr.timeout = 2000;
xhr.send();
xhr.open("GET", /somecontroller/IAmAReallySlowEndpoint, true);
xhr.ontimeout = function() {
console.log("I get called because the server was to slow to response on a succesfull request");
}
Server side endpoint (C#)
public bool IAmAReallySlowEndpoint()
{
Thread.Sleep(4000);
return true;
}
you call a server side endpoint which does not answer within 2 seconds then the ontimeout event will get thrown.
onerror
The onerror event will throw if an error in the http request happens which is the case in your example. You want to call an url that is down. Calling an url that is down will throw an error and thereby the onerror event is called.
So when you write that it works when do you:
xhr.ontimeout = xhr.onerror
You are just passing the onerror event to the ontimeout.
So to solve your problem with doing stuff if one of the endpoints you are requesting is down you should implement some retry logic kinda like you already have with a setTimeout() but deciding if the server is down or not should be based on numbers of failed request to the server instead of the ontimeout.
It's .ontimeout, not .onTimeout. Or .addEventListener("timeout", …).
I have the following problem:
I'm trying to send two Ajax requests almosts simulateously:
function ajax()
{
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4)
console.log(xhr.responseText);
}
xhr.open('GET', 'list.html', true);
xhr.send('');
}
ajax();
ajax();
The problem is that only one of them succeeds.
And if I try in the DevTools my self, if the network speed is high, they get both executed (when I quickly type the ajax() function twice in the console) while if I lower the network speed and again type them quickly only one of them succeeds.
Why is this happening? How can I avoid this auto canceling of simultaneous xhr requests?
You should use a local variable to hold the XMLHttpRequest. Since you're using a global variable, the callback function always refers to the second AJAX request that was sent. So change:
xhr = new XMLHttpRequest();
to:
var xhr = new XMLHttpRequest();
Then each callback funtion will be a closure that refers to that specific request that was sent.