Fixes #8135. Makes sure any exception thrown by Firefox when trying to access an XMLHttpRequest property when a network error occured is caught and notified as an error. Added test/networkerror.html to test the behavior.

This commit is contained in:
jaubourg 2011-02-02 13:33:02 +01:00
parent 462bb1f66a
commit b90369e8cb
2 changed files with 178 additions and 60 deletions

View file

@ -115,11 +115,22 @@ if ( jQuery.support.ajax ) {
// Listener // Listener
callback = function( _, isAbort ) { callback = function( _, isAbort ) {
var status,
statusText,
responseHeaders,
responses,
xml;
// Firefox throws exceptions when accessing properties
// of an xhr when a network error occured
// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
try {
// Was never called and is aborted or complete // Was never called and is aborted or complete
if ( callback && ( isAbort || xhr.readyState === 4 ) ) { if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
// Only called once // Only called once
callback = 0; callback = undefined;
// Do not keep as active anymore // Do not keep as active anymore
if ( handle ) { if ( handle ) {
@ -135,10 +146,9 @@ if ( jQuery.support.ajax ) {
} }
} else { } else {
// Get info // Get info
var status = xhr.status, status = xhr.status;
statusText, responseHeaders = xhr.getAllResponseHeaders();
responseHeaders = xhr.getAllResponseHeaders(), responses = {};
responses = {},
xml = xhr.responseXML; xml = xhr.responseXML;
// Construct response list // Construct response list
@ -181,11 +191,18 @@ if ( jQuery.support.ajax ) {
204 : 204 :
status status
); );
// Call complete
complete( status, statusText, responses, responseHeaders );
} }
} }
} catch( firefoxAccessException ) {
if ( !isAbort ) {
complete( -1, firefoxAccessException );
}
}
// Call complete if needed
if ( responses ) {
complete( status, statusText, responses, responseHeaders );
}
}; };
// if we're in sync mode or it's in cache // if we're in sync mode or it's in cache

101
test/networkerror.html Normal file
View file

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html>
<!--
Test for #8135
Thanks John Firebaugh for this test page based on his gist
https://gist.github.com/807090
Access this page through a web server, then stop said server and click the button.
-->
<head>
<title>
jQuery Network Error Test for Firefox
</title>
<style>
div { margin-top: 10px; }
</style>
<script src="../src/core.js"></script>
<script src="../src/support.js"></script>
<script src="../src/data.js"></script>
<script src="../src/queue.js"></script>
<script src="../src/attributes.js"></script>
<script src="../src/event.js"></script>
<script src="../src/sizzle/sizzle.js"></script>
<script src="../src/sizzle-jquery.js"></script>
<script src="../src/traversing.js"></script>
<script src="../src/manipulation.js"></script>
<script src="../src/css.js"></script>
<script src="../src/ajax.js"></script>
<script src="../src/ajax/jsonp.js"></script>
<script src="../src/ajax/script.js"></script>
<script src="../src/ajax/xhr.js"></script>
<script src="../src/effects.js"></script>
<script src="../src/offset.js"></script>
<script src="../src/dimensions.js"></script>
<script type="text/javascript">
$('button').live('click', function () {
$.ajax({
url: '/',
error: function() {
console.log( "abort", arguments );
}
}).abort();
$.ajax({
url: '/',
error: function() {
console.log( "complete", arguments );
}
});
return false;
})
</script>
</head>
<body>
<h1>
jQuery Network Error Test for Firefox
</h1>
<div>
This is a test page for
<a href="http://bugs.jquery.com/ticket/8135">
#8135
</a>
which was reported in Firefox when accessing properties
of an XMLHttpRequest object after a network error occured.
</div>
<div>Take the following steps:</div>
<ol>
<li>
make sure you accessed this page through a web server,
</li>
<li>
stop the web server,
</li>
<li>
open the console,
</li>
<li>
click this
<button>button</button>
,
</li>
<li>
wait for both requests to fail.
</li>
</ol>
<div>
Test passes if you get two log lines:
<ul>
<li>
the first starting with "abort",
</li>
<li>
the second starting with "complete",
</li>
</ul>
</div>
<div>
Test fails if the browser notifies an exception.
</div>
</body>
</html>