Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect XHR error is really due to browser stop or click to new page

Tags:

While my page is loading content via XHR, if the user clicks the stop button or clicks to go to another page, the XHR error() function is called. This wouldn't normally be a big deal except for the user shock of seeing lots of (red) error messages on the page.

The messages are valid - there was indeed an error retrieving the content - but it's due to the user interaction, not because of a system failure.

Is there a way to distinguish between a (404 | 500 | timeout error) and an error caused by the fact that the user hit the browser's stop button ?

EDIT: I am using Dojo (hence the error function reference), but I believe this would be a situation that is common across any XHR implementation. I will look into readyState of the xhr object when error() is called

like image 361
olore Avatar asked Sep 18 '09 03:09

olore


1 Answers

To distinguish between HTTP errors (404, 401, 403, 500, etc..) and request abortion errors (i.e. the user pressed Esc or navigated to other page) , you can check the XHR.status property, if the request has been aborted the status member will be zero:

document.getElementById('element').onclick = function () {    postRequest ('test/', null, function (response) { // success callback     alert('Response: ' + response);    }, function (xhr, status) { // error callback     switch(status) {        case 404:          alert('File not found');          break;        case 500:          alert('Server error');          break;        case 0:          alert('Request aborted');          break;        default:          alert('Unknown error ' + status);      }    });  }; 

A simple postRequest function:

function postRequest (url, params, success, error) {     var xhr = XMLHttpRequest ? new XMLHttpRequest() :                               new ActiveXObject("Microsoft.XMLHTTP");    xhr.open("POST", url, true);    xhr.onreadystatechange = function(){      if ( xhr.readyState == 4 ) {        if ( xhr.status == 200 ) {      success(xhr.responseText);        } else {      error(xhr, xhr.status);        }      }    };    xhr.onerror = function () {      error(xhr, xhr.status);    };    xhr.send(params);  }  

Run the above snippet here.

like image 126
Christian C. Salvadó Avatar answered Sep 21 '22 14:09

Christian C. Salvadó