I have a list of IP addresses to a couple of servers that need to be pinged to see if they are running. Their IP addresses are stored in the data-ip-address
attributes of a list of span
elements, the Javascript function reads them in order, pings each of them, and displays the result. A more simplified version of the full function is this:
function pingServers() {
if($('span[data-ping-this]').length > 0) {
element = $('span[data-ping-this]:first');
$(element).removeAttr('data-ping-this');
var url = $(element).attr('data-ip-address');
$.ajax({
url: url,
dataType: 'jsonp',
timeout: 4000,
success: function(response) {
displaySuccess();
},
error: function(something){
displayWarning();
}
});
setTimeout(function(){
pingServers();
}, 1000);
}
}
The main thing is that there is a timeout defined, and that timeout definitely is working, because after 4 seconds of no response, I do get my warning displayed. But my browsers, both Firefox and Chrome, are still showing a status message that they are connecting (in the bottom-left corner). Firefox shows the Connecting to <ip address>
message, while Chrome only shows Connecting...
, and the favicon in the tab keeps being the animated loading icon.
If I keep the tab open, this goes on forever. If I change the tabs enough times, the status message (and the loading icon) eventually goes away (never without changing tabs). Another interesting thing is that, after it goes away, if I initiate this function again via Javascript (not by reloading the page), then the Connecting
message doesn't show up at all anymore. Even though it should in this case. How I do this, is by simply returning the data-ping-this
attribute to one of the span
elements, and then run the function again.
$('span:first').attr('data-ping-this', 'true');
pingServers();
So, is this something that can be fixed on a jQuery side, and if so, how? Or is it a bug in the browsers?
答案 0 :(得分:1)
Shortly: This is the bug of JSONP.
Explanation: The JSONP is not a real XmlHttpRequest, so it is not an Ajax call. JSONP is a hacky attempt to perform cross-domain requests by requesting some remote script from a different domain, see wikipedia to learn more.
What jQuery does inside, it performs this JavaScript call by adding
<script src='your_pinging_address'></script>
This is the only way to make a JSONP request. Then it comes to timeout, which they do most likely with setTimeout
, so they found out on jQuery side that timeout is reached and they call your callback
function; meanwhile the browser has no idea about this timeout because it is artificial, so it goes on waiting for a remote script.
In other words: every Ajax request but JSONP has a timeout on the browser side. The JSONP timeout is a piece of jQuery art.
I cannot point you to a line of the code where they serve the timeout in the current jQuery. I had a similar problem couple of years ago with some old jQuery version, but logically everything should stay as it was.