I recently updated an app that uses Dojo to sent asynchronous petitions to my server which serves these petitions with cgi.
My problem is as follows. So for example the variable that makes the requests is
parent.sc_dojo.io.script.jsonp_sc_dojoIoScript2
This new service takes too long to send the response approximately 40 - 60 seconds, and after this time the variable parent.sc_dojo.io.script.jsonp_sc_dojoIoScript2 appears as UNDEFINED
I made an analysis using firebug, see the following image for major details.
The petition to the server has the following data:
Connection Keep-Alive
Content-Type text/javascript; charset=utf-8
Date Tue, 10 Sep 2013 12:39:22 GMT
Keep-Alive timeout=5, max=100
Server Apache/2.2.22 (Ubuntu)
Transfer-Encoding chunked
The timeout ranges from 5 to 100, I don't really know the units of this measure, Any ideas?
About Connection Keep-Alive
When a client browser sends the "Connection: Keep-alive" header to an HTTP/1.1 server, the browser is saying "hey, I want to carry on a long conversation, so don't close the connection after the first exchange."
The keep-alive "timeout" value is in seconds. The "max" value is unit-less, representing the maximum number of requests to service per connection. Taken together, these augment the client's request to "hey, I want to carry on a long conversation, so don't close the connection after the first exchange BUT if nothing exchanges in 5 seconds (timeout) OR if more than 100 requests go back and forth (max), I'm ok with you closing the connection." The server responds with the actual values it will service for timeout and max.
The penalty for a closed connection is that a new one has to be opened up. Some modern browsers limit the number of simultaneous open connections, so keeping these values too small may introduce latency (while your app waits for free connections). On the other hand, the server need not agree to the timeout and max values requested: the server sets its own limits.
See these articles for details:
http://www.feedthebot.com/pagespeed/keep-alive.html
http://en.wikipedia.org/wiki/HTTP_persistent_connection
http://www.hpl.hp.com/personal/ange/archives/archives-95/http-wg-archive/1661.html
About dojo timeouts
I don't see your code or dojo version, but dojo does allow you to set how long it will wait for a response via the timeout property in the XHR request. The default timeout is "never". Code below.
In practice, "never" is misleading: browsers have their own defaults for keep-alive timeouts and upstream routers might have their own timeouts.
Try to keep it short. If the response takes more than 15 seconds, there may need to be a different design approach to the problem: reverse ajax, polling, combined response, etc.
require(['dojo/request/xhr'], function (xhr) {
xhr(
'http://www.example.com/echo',
{ timeout:15000 /* change this, units are milliseconds */, handleAs:'json' }
).then(function (r) {
console.log(r);
});
});
The specific problem
Ok, finally. If you have a long server side run, here's what I would do:
Send a request from client to server that starts the job
Server responds with a unique URL that can be polled for status
In Javascript, use setInterval() to periodically check the returned URL for status
When the URL shows "status" done, kill the setInterval and issue a final call to get the result
Related
Node.js supports sending a 102 Processing status code since v10, but I'm not sure how this can be used.
Is it something the browser only uses internally (like it delays the timeout event) or can we access this temporary status in any way?
I'd like to let my javascript code know "hey, I'm working on this, sit tight". Sending a temporary status seems like the easiest way out.
Another option is to work with a 202 status, but that requires a lot more changes.
You are right.
102 PROCESSING
An interim response used to inform the client that the server has accepted the complete request, but has not yet completed it.
This status code SHOULD only be sent when the server has a reasonable expectation that the request will take significant time to complete. As guidance, if a method is taking longer than 20 seconds (a reasonable, but arbitrary value) to process the server SHOULD return a 102 (Processing) response. The server MUST send a final response after the request has been completed.
Methods can potentially take a long period of time to process, especially methods that support the Depth header. In such cases the client may time-out the connection while waiting for a response. To prevent this the server may return a 102 Processing status code to indicate to the client that the server is still processing the method.
You can see it at https://httpstatuses.com/102 or https://www.rfc-editor.org/rfc/rfc2518#section-10.1
I have created a Javascript based REST API page (private chrome extension) which integrates with the Oracle tool and fetches response. It works fine if the response is received within around 3-5 mins however, if it takes additional time it gives ERR_EMPTY_RESPONSE error.
I have tried xhr.timeout but still it gives the same ERR_EMPTY_RESPONSE error. How can we ask the Javascript to wait for more time?
Thanks..
If you are making ajax call to server and want to increase waiting time of response
then you need to set "timeout" interval at server side.
In nodejs I am giving the way that you can apply at server side to increase timeout period.
in app.js file(express framework)
write down following code
app.use(function(req, res, next) {
//Set time out for request to 24hour
req.connection.setTimeout(24 * 60 * 60 * 1000);
next();
});
You can also refer this
HTTP keep-alive timeout
Proper use of KeepAlive in Apache Htaccess
you need to do this at server side
NOTICE: I replaced my polling system with websockets but I still want to know the answer to my questions above.
I'm trying to reduce an AJAX request of a traditional-polling message system, but I don't know how to get it:
$chatbox = $("#chatbox");
setInterval(function(){
// I send the sha1 of the chatbox html content to verify changes.
$.post("post.php", {checksum: hex_sha1($chatbox.html())}, function (data, status) {
switch (status) {
case "success":
// If version of "post.php" checksum is different than mine (there are changes) data isn't empty; I assign data as the new content of the chatbox.
if(data){
$chatbox.html(data);
$chatbox.scrollTop($chatbox[0].scrollHeight);
}
break;
default:
$chatbox.html('Connection error...');
break;
}
});
}, 1000);
Well, As you see I use an setInterval() with 1000 miliseconds as parameter and thanks to the SHA1 checksum system I can reduce the size of all AJAX response to 343 B (except when "post.php" returns some new message, obviously)
Questions:
Why all my AJAX requests have ever the same size (343 B) even though I change the SHA1 (20 B) hash to MD5 (16 B)?
My checksum variable (SHA1) occuppies 20 B: Where do the remaining 323 B?
Could I reduce more the AJAX request size? How?
NOTE:
hex_sha1() is a implementation of SHA1 algorithm for Javascript: http://pajhome.org.uk/crypt/md5/sha1.html
NOTE 2:
Unfortunately I can't use an Server-Push Technique like node.js. I can only use Javascript (client-side) and PHP.
Why not use the plain javascript AJAX Request? Maybe your AJAX data is too long, that's why it has a large size: and the only thing you can do for it is to make the AJAX data have a few data.
What do you want? like Facebook AJAX Polling? Do it like this on the server PHP:
$chat_data = "(this is the chat data variable if there is no chat data it will idle)";
while (!$chat_data) {
// when there's no chat data let's idle the request without disconnecting
// the client from the AJAX request.
sleep(1);
}
exit(json_encode($chat_data));
On JavaScript Client Side:
function repoll () {
chat_poll = new XMLHttpRequest();
// the chat_req variable is for sending POST data to the server.
chat_req = new FormData();
chat_req.append("do", "chatpoll");
chat_poll.open("POST", "post.php");
chat_poll.send(chat_req);
chat_poll.onload = function () {
// do something here with the chat data
// repoll the server
repoll();
}
repoll();
By doing this, your implementing the Facebook like server polling.
For the websocket example in JavaScript client side:
web_socket = new WebSocket("ws://[thesocket]:[theport]");
web_socket.onmessage = function (w) {
// do something here. this will fire if messages is received from the websocket.
// you will get the message from w.data variable.
alert("Data Received: " + w.data);
}
// to send data to the web socket do this:
web_socket.send("the data you want. I prefer JSON for sending configuration and chat data or XML if you want");
Here's my take on your questions, even though you'd better of using a library like socket.io with fallback support for older browsers (simulating websockets via long-polling or such).
Why all my AJAX requests have ever the same size (343 B) even though I
change the SHA1 (20 B) hash to MD5 (16 B)?
Most HTTP communication between browser and server by default is compressed with gzip. The bulk of your request/response stream consists of HTTP headers where 4 bytes of difference in your hashing algorithm's output may not make a difference effectively due to the gzip compression.
My checksum variable (SHA1) occuppies 20 B: Where do the remaining 323 B?
See above, and to see for yourself, you could use a http monitor, tcpdump or developer tools to see the raw data transferred.
Could I reduce more the AJAX request size? How?
WebSocket has a lot less footprint compared to HTTP requests, so using it seems the best option here (and polling in intervals is almost never a good idea, even without WebSocket you would be better off implementing long-polling in your server).
I have assembled a simple page with a jQuery $.post request. It produces a request header that's in the form:
POST /post_.js HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: */*
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://localhost/test.html
Content-Length: 49
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
You can see the response and request headers by using Firebug on Firefox or F12 on Chrome.
In my opinion the extra bytes are those involved in the Http request.
I have a web application that lets the browser cache AJAX requests result for a long time. I have found out how to make a request that bypasses the cache entirely, when probable modifications are detected. But I would want to let the user trigger a data refresh.
In this scenario, I'd like the browser to check with the server if the cache is stalled but use it if it is not (that is, if the server responds with a 304 code). The goal is to spare the loading time because the data is huge.
The server includes the following headers in all responses:
Cache-Control: private, max-age=604800
Last-Modified: ... # actual last modification date
I managed to burst the cached object entirely in Chrome (not tested other browsers yet) by using the following HTTP headers in the request:
Cache-Control: max-age=0
If-Last-Modified: Tue, 01 Jan 1970 01:00:00 +0100
The If-Last-Modified line is the one that really has an effect. Chrome seems to ignore the Cache-Control header in the request.
I have also found that using Cache-Control: must-revalidate in the server response forces the browser to validate its cache with the server for each request.
But is there any way to revalidate for just one precise request, decided on the client-side?
Note that I'm not specially attached to doing this with HTTP headers, so any other method that I would not be aware of is welcome!
you can add a url parameter which value base on time to clean cache for just one precise request.
$.ajax({
url:"/questions?nocache="+Date.now(),
"success":function(data){
console.log(data);
}
});
How do I send an HTTP response that any client would cache forever (or until its cache is cleared), such that when the browser needs that resource, it makes no HTTP request and instead retrieves the HTTP response from the local file system?
Usage note: this is for versioned client code in an Ajax application. Everything is accessed through the uncacheable example.com/front.htm, which merely contains a script tag linking to example.com/currentversion/bootstrap.js which is cached indefinitely. Because the uncacheable HTML file determines the current version, there is no need for the client to update scripts.
According to the RFC, "to mark a response as 'never expires,' an origin server sends an Expires date approximately one year from the time the response is sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future."
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21.
I don't know what the reasoning behind the one-year limitation is, so take it for what it is.
Cache until 2038. You can't go any farther than that (reliably) because of the 32-bit Unix Epoch bug. Use this header:
Expires: Sun, 17 Jan 2038 19:14:07 GMT