I'm trying to track the progress of an archive compression through requesting a txt file made, and updated by PHP via JQuery $.get().
The process works except for 1 or 2 requests that fail at random intervals and return the following:
readyState: 0
responseText:
status: 0
statusText: error
In Chrome and Opera, there is also this next to the failed requests: "net::ERR_CONTENT_LENGTH_MISMATCH"
Here is the code in question:
function check_compression(archive_name, progress_file, unique_compression_id) {
$.ajaxSetup ({
cache: false
});
var request = $.get($.trim(progress_file));
request.success(function(data) {
var percent = parseInt(data);
if(percent != 100) {
setTimeout(function() {
check_compression(archive_name, progress_file, unique_compression_id);
}, 100);
} else {
// Not finished
}
});
request.error(function(jqXHR, textStatus, errorThrown) {
// Just some error reporting
setTimeout(function() {
check_compression(archive_name, progress_file, unique_compression_id);
}, 500);
});
}
I have done a bit of research and ruled out possible situations:
Same Origin Policy issue: All requests are done to a file on the same server. The progress_file var will be in a format such as: tmp_file.txt
AdBlock is not enabled.
Related
I have a website where users can work on projects and their work gets automatically saved to my database. Every couple seconds on my site an ajax (post) call occurs (usually in jquery) to check permissions and what not.
With one section of code is there any way so check if any of the ajax calls on your page fail. I don't want to have to go to every individual call and add a block of code to the end.
Basically this is so I can alert the user if they have lost connection or if something is going wrong.
You can use the jQuery event ajaxError. It will be triggered whenever an Ajax request completes with an error:
$(document).ajaxError(function() {
console.error('Error');
});
Check out the documentation.
$(document).ready(function(){
//ajax setup settings
$.ajaxSetup ({
cache: false,
async: false,
statusCode: {
404: function() {
alert('Page not found!');
},
500: function(jqXHR, textStatus) {
alert('Server side: ' + textStatus);
}
}
});
});
I hope this may help you
I would suggest you to override the original jquery ajax function.
var $_ajax = $.ajax; // reference to original ajax
$.ajax = function(options) {
if (options.error) {
// reference to original error callback
var originalErrorHandler = options.error;
var errorHandlerContext = options.context ? options.context : $;
var customErrorHandler = function(xhr, status, error) {
// notify error to your user here
};
// override error callback with custom implementation
options.error = customErrorHandler;
};
return $_ajax.apply($, arguments);
}
I got this piece of cake function:
$.ajax({
url: 'Example.html',
DataType: 'text',
cache: false,
success: function (){
alert ('Yes');
},
error: function (){
alert ('No');
}
});
This function, works just fine, BUT ONLY FOR THE VERY FIRST TIME), from the second time on, the function sends the following error to Chrome:
GET http://MyServer.com/Example.html?_=1406469092100 net::ERR_FAILED
The same situation happens equally with this second JS option:
function doesConnectionExist() {
var xhr = new XMLHttpRequest();
var file = "http://www.example.com/Example.html";
var randomNum = Math.round(Math.random() * 10000);
xhr.open('HEAD', file + "?rand=" + randomNum, false);
try {
xhr.send();
if (xhr.status >= 200 && xhr.status < 304) {
alert ('Yes');
} else {
alert ('No');
}
} catch (e) {
alert ('No');
}
}
1) In the Ajax scenario I just indicate cache: "false"!
2) In the JavaScript scenario I am using random arguments to avoid cache!
Is there anything I am missing? in the Server side??
Please help...
It may be a server problem? I have created a jsFiddle and it seems to work like it should. I wrapped your $.ajax method in a ping function and run it 3 times fetching a jsfiddle resource.
function ping(i) {
$.ajax({
url: '/img/logo.png',
success: function () {
screen.log({text: 'attempt #'+(i+1)+ ' Yes', timed: +i, clear: 'no'});
},
error: function (d){
screen.log({text: 'attempt #'+(i+1)+ ' Nope', timed: +i, clear: 'no'});
}
});
}
See the already mentioned jsFiddle for output
Note: in your second code snippet your supply false as the third paramater to the open method, which means asynchronous = false, so the XHR there is synchronous. The cache: false parameter in the first snippet appends a random reuqeststring to the request. This prevents the browser from caching the fetched resource. I suppose it's not really necessary here.
After hours and hours of try an error I found the Answer....dedicated for those guys who are facing the same problem I did:
In my case this was not a common Web Page, it was an "Offline Web Page" with a Manifest File in it.
Simply in the section "NETWORK" of the manifest file included the file "Example.html" and that's it.
That's all folks!
I have the following example which uses the progress events in XHR2 to display a progress bar to the user when performing an AJAX request:
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function(evt){
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
if(percentComplete >= 100){
$('#loading-bar').find('.bar').css({'width': percentComplete + '%'});
$('#loading-bar')
.find('.bar')
.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() {
$('#loading-bar').fadeOut(function(){
$('#loading-bar').find('.bar').css({'width': ''});
});
});
} else {
$('#loading-bar').find('.bar').css({'width': percentComplete + '%'});
}
}
}, false);
return xhr;
},
type: 'GET',
url: 'Test.html',
success: function (response) {
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
However for browsers that don't support XHR2, the bar won't animate nor will the loading-bar element be faded out from the DOM.
How can I implement a fallback? As I don't want to just fade the loading bar out on success as that will then conflict with the progress events for browsers that DO support it.
Or even better is it possible to get the progress by alternate means?
If it's download progress, we can do it when xhr.readyState >= 3. Just read the xhr.responseText.length, and then divide it by parseInt(xhr.getResponseHeader('Content-Length')) (assuming the server provides this header and it's same origin or with correct CORS header).
If it's upload progress, I don't know any method to polyfill it purely within the client-side. We can create an id for every upload session, and use another xhr to pull the upload receiving progress from the server. However that requires complicated implementation on the server-side. There are many such implementations in common languages, for example for PHP or .NET. You can look into them and implement your own.
Try using .onreadystatechange() with .readyState:
getter.onreadystatechange = function() {
if (loading) { //If the loading element has been loaded...
if (this.status === 200) { //If this.status is already 200...
loading.style.width = this.readyState*25+"%"; //This sets the width of loading according to this.readyState
if (this.readyState === 4) {
//We hide loadingBar and do stuff when we're done.
loadingBar.style.display = "none";
[do stuff]
}
}
}
};
If you're accepting 100 Continue statuses, you might also want to account for that into your loading bar. The way this is now, it's at a standstill for a while, but then zooms to 100% when it gets to the status 200 OK and the readyState property goes from 2 to 4.
Here's the fiddle: http://jsfiddle.net/NobleMushtak/QRuU6/
I'm able to check When there is no internet in my phonegap app using navigator.network.connection.type but when the connection is slow(almost not there) how to check detect such situation using any jquery/javascript code??
You could use setTimeout() to set a maximum time for a request:
var timeout;
var xhr = $.ajax({
type: "GET",
url: "http://myservice.com/jsonp",
data: data,
success: function(msg){
// All went OK
if(timeout != null) clearTimeout(timeout);
}
});
timeout = setTimeout(function() {
// Request took >= 10 seconds
// We could kill it?
xhr.abort();
// Or send a message to the user and ask whether they want to continue
if(!confirm("Network connection is taking longer than usual to complete. Continue waiting?")) {
xhr.abort();
}
}, 10000);
This is my code on shoutbox update :
function updateShoutbox(){
$("#shoutdiv").load("shoutbox.php", { 'action': 'update' } ,
function (responseText, textStatus, req) {
if (textStatus == "error") {
return false;
}
});
}
$(document).ready(function(){
updateShoutbox();
var auto_refresh = setInterval(
function ()
{
updateShoutbox();
$("#shoutdiv").scrollTop($("#shoutdiv")[0].scrollHeight);
}, 6000);
It returns error each some minutes :
shoutbox.php returned error:
Service Unavailable
Is there anyway to handle this error and hide it somehow ?
I edited my code so to stop showing any error on shoutbox update, but it still shows this error each minutes.
Ok, so let's take this for example:
$(document).ready(function(){
(function iterate(i) {
if (!!i) {
console.log('iteration #', i--);
setTimeout(function next(){
iterate(i);
}, 1000);
}
})(10);
});
http://jsfiddle.net/userdude/6C8yp/
If you look at the console, you'll see it counts down until i is equal to 0, or i is not given (that's what the !! is for there). What I'm doing here is looping each second, but only after the last loop has finished. I'm feeding my loop.
Looking at what you have here, I might do this instead:
$(document).ready(function($){
var $shoutbox = $("#shoutdiv"),
timer;
(function update(){
var opts = {
url: 'shoutbox.php',
action: 'update',
complete: wait
};
$.ajax(opts);
function wait(res, status, req){
if (status == 200) {
$shoutbox
.append(res)
.scrollTop($shoutbox[0].scrollHeight);
timer = setTimeout(update, 6000);
}
}
})();
});
http://jsfiddle.net/userdude/whsPn/
http://jsfiddle.net/userdude/whsPn/1/
Ok, so what we have above should mostly emulate the code you have in the question. You'll note that I have the complete: wait part in there, and the setTimeout() is in that callback. And.. it's only called if the status returned is 200 (success).
Now, there you could turn complete: wait to success: wait, and take out the status == 200 if statement altogether. Of course, if you do want to run the update again, but maybe do something different, this is your chance.
Also note, in the fiddle linked I've got some dummy code in there. So don't just copy/page what's in the fiddle, or you'll have errors and it won't run at all.
EDIT: Oops, found an error with url =. Fixed.
If you want to "hide" your error instead of looking for the cause of the error in the first place, try this in your callback function in the $.load:
function (responseText, textStatus, req) {
if(req.status!=200&&req.status!=302) {
return false;
}
//update the shoutbox
}
At least to me this is what seems to be the most reliable way to prevent random errors from getting through your checks.