Skip to main content

Bug Tracker

Side navigation

#8177 closed bug (patchwelcome)

Opened February 04, 2011 02:58PM UTC

Closed February 11, 2011 11:25PM UTC

Last modified March 13, 2012 02:38PM UTC

Browser inconsistencies with ajax, ifmodified, notmodified and ApplicationCache

Reported by: blabber Owned by: blabber
Priority: low Milestone: 1.next
Component: ajax Version: 1.5
Keywords: Cc: jaubourg
Blocked by: Blocking:
Description

jQuery.ajax does not return consistent results for requests on files from the ApplicationCache, online files and when setting ifModified to true or false.

I have done a number of test on different browsers / operating systems. A test consists of 4 different requests, each is executed two times in a row:

1. Read file from application cache, ifModified = false.

2. Read file from network, ifModified = false.

3. Read file from application cache, ifModified = true.

4. Read file from network, ifModified = true.

The results below show 6 different results. I discovered the problem because of the problems with Android 2.2 and Safari 5.0 returning no data and 'notmodified' status for normal request. This problem only occures, if the browser is closed with the application cache filled with the test case!

The fix this, ifModified can be checked before setting the textStatus to 'notmodified'. Otherwise jQuery can just return the responseText otherwise.

The patch would be to change:

if ( status === 304 ) {

to

if ( s.ifModified && status === 304 ) {

I have not further investigated the problems with ifModified set to true and I am not even sure, what the correct result should be. I would guess the first result block is ok.

Firefox 4.0b, Safari, Chrome and newer androud versions seem to have some bugs?

Firefox 3.6.13 Ubuntu 10.10, Firefox 3.6.12 Windows XP, IE 8.0.7600.16385 Windows 7,
IE 9.0.7930.16406 Windows 7, Android 1.6 Browser

cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified


Firefox 4.0b10 Windows 7

cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success


Google Chrome 8.0.552.237 Windows XP, Google Chrome 9.0.597.84 beta Ubuntu 10.10,
Android Browser 2.2 (? Samsung Tab)

cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified


Android Browser 2.2 (? Samsung Tab)

ApplicationCache loaded before browser start
cached1.txt  ifModified: false   success   data: -      jqXHR.responseText: ok     textStatus: notmodified
cached1.txt  ifModified: false   success   data: -      jqXHR.responseText: ok     textStatus: notmodified
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: -      jqXHR.responseText: ok     textStatus: notmodified
cached2.txt  ifModified: true    success   data: -      jqXHR.responseText: ok     textStatus: notmodified
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success


Safari 5.0 (7533.16) Windows XP, Safari 5.03 (6533.19.4) MacOSX

ApplicationCache loaded in same browser session
cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified

ApplicationCache loaded before browser start
cached1.txt  ifModified: false   success   data: -      jqXHR.responseText: ok     textStatus: notmodified
cached1.txt  ifModified: false   success   data: -      jqXHR.responseText: ok     textStatus: notmodified
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    success   data: -      jqXHR.responseText: ok     textStatus: notmodified
cached2.txt  ifModified: true    success   data: -      jqXHR.responseText: ok     textStatus: notmodified
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified
Attachments (0)
Change History (16)

Changed February 04, 2011 03:14PM UTC by jitter comment:1

_comment0: Thanks for taking the time to contribute to the jQuery project by writing a bug report. \ \ It would be nice if you could provide more information so that we are able to reproduce your tests by: \ \ - (if possible) recreating the tests as reduced test cases on http://jsfiddle.net \ - providing links to the "live tests" on some homepage \ - providing a link where we can download your "test suite" (consisting of all files need to reproduce your tests) \ \ and by including/posting detailed instructions on what steps need to be taken (opening which page, refreshing, steps in which order, emptying cache, ....) to reproduce your results. \ \ That would allow us to investigate this issue further, as it's difficult to tell by your description and the "output of your tests" what exactly is going on. Also make sure to read the link given below, in order to provide a most useful bug report. \ \ ----- \ [http://docs.jquery.com/How_to_Report_Bugs How to report bugs]1296832511891854
cc: → jaubourg
component: unfiledajax
owner: → blabber
priority: undecidedlow
status: newpending

Thanks for taking the time to contribute to the jQuery project by writing a bug report.

It would be nice if you could provide more information so that we are able to reproduce your tests by:

  • (if possible) recreating the tests as reduced test cases on http://jsfiddle.net
  • providing links to the "live tests" on some homepage
  • providing a link where we can download your "test suite" (consisting of all files need to reproduce your tests)

and by including/posting detailed instructions on what steps need to be taken (opening which page, refreshing, steps in which order, emptying cache, ....) to reproduce your results and at the same time describing what are the expected results for your different tests.

That would allow us to investigate this issue further, as it's difficult to tell by your description and the "output of your tests" what exactly is going on. Also make sure to read the link given below, in order to provide a most useful bug report.


How to report bugs

Changed February 04, 2011 03:26PM UTC by blabber comment:2

_comment0: Replying to [comment:1 jitter]: \ \ I may have time to setup a running test case on a public server on monday. But I think I can also just post the code inline, as it is not too complicated or long: \ \ index.html: \ {{{ \ <html manifest="cache.manifest"> \ \ <head> \ <script src="jquery.js"></script> \ </head> \ \ <body> \ <pre id="log"></pre> \ \ <script> \ function log(text) { $('#log').append(text + '<br>'); }; \ \ var i = 0; \ var urls = ['cached1.txt', 'online1.txt', 'cached2.txt', 'online2.txt']; \ function test() { \ if (i > 7) \ return; \ \ load(urls[Math.floor(i / 2)], i < 4 ? false : true); \ ++i; \ }; \ \ function load(url, ifModified) { \ $.ajax({ \ dataType: 'text', \ ifModified: ifModified, \ url: url \ }).success(function(data, textStatus, jqXHR) { \ log(url + ' ifModified: ' + (ifModified ? 'true ' : 'false') + ' success ' + \ ' data: ' + (data === url + 'x' ? 'ok ' : (!data ? '- ' : 'error')) + \ ' jqXHR.responseText: ' + (jqXHR.responseText === url + 'x' ? 'ok ' : (!jqXHR.responseText ? '- ' : 'error')) + \ ' textStatus: ' + textStatus); \ if (jqXHR.responseText && jqXHR.responseText !== url + 'x') \ log('responseText: ' + jqXHR.responseText); \ }).error(function(jqXHR, textStatus, errorThrown) { \ log(url + ' ifModified: ' + (ifModified ? 'true ' : 'false') + ' error ' + \ ' data: - ' + \ ' jqXHR.responseText: ' + (jqXHR.responseText === url + 'x' ? 'ok ' : ((!jqXHR.responseText) ? '- ' : 'error')) + \ ' textStatus: ' + textStatus); \ if (jqXHR.responseText && jqXHR.responseText !== url + 'x') \ log('responseText: ' + jqXHR.responseText); \ }).complete(function () { \ test(); \ }); \ }; \ \ $(document).ready(function() { \ window.setTimeout(test, 2000); \ }); \ \ </script> \ \ </body> \ </html> \ }}} \ \ cache.manifest: \ {{{ \ CACHE MANIFEST \ #v1 \ \ NETWORK: \ online1.txt \ online2.txt \ \ CACHE: \ index.html \ jquery.js \ cached1.txt \ cached2.txt \ }}} \ \ cached1.txt, cached2.txt, online1.txt, online2.txt \ Content is filename + 'x', e.g.: \ {{{ \ cached1.txtx \ }}} \ \ and obviously you will need jquery.js in the folder.1296833260692439
status: pendingnew

Replying to [comment:1 jitter]:

I may have time to setup a running test case on a public server on monday. But I think I can also just post the code inline, as it is not too complicated or long.

Just create all files in a folder and access index.html. For Android and Safari it may change the results, if you close the browser and open it again with the application cache filled.

index.html:

<html manifest="cache.manifest">

<head>
	<script src="jquery.js"></script>
</head>

<body>
<pre id="log"></pre>

<script>
function log(text) { $('#log').append(text + '<br>'); };

var i = 0;
var urls = ['cached1.txt', 'online1.txt', 'cached2.txt', 'online2.txt'];
function test() {
	if (i > 7)
		return;

	load(urls[Math.floor(i / 2)], i < 4 ? false : true);
	++i;
};

function load(url, ifModified) {
	$.ajax({
		dataType: 'text',
		ifModified: ifModified,
		url: url
	}).success(function(data, textStatus, jqXHR) {
		log(url + '  ifModified: ' + (ifModified ? 'true ' : 'false') + '   success ' +
			'  data: ' + (data === url + 'x' ? 'ok   ' : (!data ? '-    ' : 'error')) +
			'  jqXHR.responseText: ' + (jqXHR.responseText === url + 'x' ? 'ok   ' : (!jqXHR.responseText ? '-    ' : 'error')) +
			'  textStatus: ' + textStatus);
		if (jqXHR.responseText && jqXHR.responseText !== url + 'x')
			log('responseText: ' + jqXHR.responseText);
	}).error(function(jqXHR, textStatus, errorThrown) {
		log(url + '  ifModified: ' + (ifModified ? 'true ' : 'false') + '   error   ' +
			'  data: -    ' +
			'  jqXHR.responseText: ' + (jqXHR.responseText === url + 'x' ? 'ok   ' : ((!jqXHR.responseText) ? '-    ' : 'error')) +
			'  textStatus: ' + textStatus);
		if (jqXHR.responseText && jqXHR.responseText !== url + 'x')
			log('responseText: ' + jqXHR.responseText);
	}).complete(function () {
		test();
	});
};

$(document).ready(function() {
	window.setTimeout(test, 2000);
});

</script>

</body>
</html>

cache.manifest:

CACHE MANIFEST
#v1

NETWORK:
online1.txt
online2.txt

CACHE:
index.html
jquery.js
cached1.txt
cached2.txt

cached1.txt, cached2.txt, online1.txt, online2.txt

Content is filename + 'x', e.g.:

cached1.txtx

and obviously you will need jquery.js in the folder.

Changed February 05, 2011 02:09AM UTC by jaubourg comment:3

resolution: → fixed
status: newclosed

Fixes #8177. XHR transport now considers 304 Not Modified responses as 200 OK if no conditional request header was provided (as per the XMLHttpRequest specification).

Changeset: d6fbbe1080fdcaf8eb22753eddf000aeb7d99545

Changed February 05, 2011 02:10AM UTC by jaubourg comment:4

milestone: 1.next1.5.1

blabber, can you confirm this fixes your issue?

Changed February 07, 2011 09:15AM UTC by blabber comment:5

_comment0: That was fast. :-)[[BR]] \ The patch fixes the browser differences for the cases with ifModified=false. The differences found with ifModified=true remain as above. \ \ Replying to [comment:4 jaubourg]: \ > blabber, can you confirm this fixes your issue? \ 1297072677221123
_comment1: Edit: \ Tested the wrong version, with the fix I mentioned above. Sorry. The current git-Version does not fix the bug, but seems to give empty data and textStatus: \ \ {{{ \ Safari (page loaded, Safari closed, Safari opened, page loaded again): \ \ cached1.txt ifModified: false error data: - jqXHR.responseText: ok textStatus: \ cached1.txt ifModified: false error data: - jqXHR.responseText: ok textStatus: \ online1.txt ifModified: false success data: ok jqXHR.responseText: ok textStatus: success \ online1.txt ifModified: false success data: ok jqXHR.responseText: ok textStatus: success \ cached2.txt ifModified: true error data: - jqXHR.responseText: ok textStatus: \ cached2.txt ifModified: true error data: - jqXHR.responseText: ok textStatus: \ online2.txt ifModified: true success data: ok jqXHR.responseText: ok textStatus: success \ online2.txt ifModified: true success data: - jqXHR.responseText: - textStatus: notmodified \ }}} \ \ That was fast. :-)[[BR]] \ The patch fixes the browser differences for the cases with ifModified=false. The differences found with ifModified=true remain as above. \ \ Replying to [comment:4 jaubourg]: \ > blabber, can you confirm this fixes your issue? \ 1297153503714846
_comment2: Edit: \ Tested the wrong version, with the fix I mentioned above. Sorry. The current git-Version does not fix the bug, but seems to give empty data and textStatus: \ \ {{{ \ Safari (page loaded, Safari closed, Safari opened, page loaded again): \ \ cached1.txt ifModified: false error data: - jqXHR.responseText: ok textStatus: \ cached1.txt ifModified: false error data: - jqXHR.responseText: ok textStatus: \ online1.txt ifModified: false success data: ok jqXHR.responseText: ok textStatus: success \ online1.txt ifModified: false success data: ok jqXHR.responseText: ok textStatus: success \ cached2.txt ifModified: true error data: - jqXHR.responseText: ok textStatus: \ cached2.txt ifModified: true error data: - jqXHR.responseText: ok textStatus: \ online2.txt ifModified: true success data: ok jqXHR.responseText: ok textStatus: success \ online2.txt ifModified: true success data: - jqXHR.responseText: - textStatus: notmodified \ }}} \ \ (Edit: removed) \ \ Replying to [comment:4 jaubourg]: \ > blabber, can you confirm this fixes your issue? \ 1297153526613306

Edit:

Tested the wrong version, with the fix I mentioned above. Sorry. The current git-Version does not fix the bug, but seems to give empty data and textStatus:

Safari (page loaded, Safari closed, Safari opened, page loaded again):

cached1.txt  ifModified: false   error     data: -      jqXHR.responseText: ok     textStatus: 
cached1.txt  ifModified: false   error     data: -      jqXHR.responseText: ok     textStatus: 
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
cached2.txt  ifModified: true    error     data: -      jqXHR.responseText: ok     textStatus: 
cached2.txt  ifModified: true    error     data: -      jqXHR.responseText: ok     textStatus: 
online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified

(Edit: removed old content)

Replying to [comment:4 jaubourg]:

blabber, can you confirm this fixes your issue?

Changed February 07, 2011 01:25PM UTC by jaubourg comment:6

resolution: fixed
status: closedreopened

Changed February 07, 2011 01:25PM UTC by jaubourg comment:7

owner: blabberjaubourg
status: reopenedassigned

Changed February 07, 2011 03:55PM UTC by jaubourg comment:8

Replying to [comment:5 blabber]:

Edit: Tested the wrong version, with the fix I mentioned above. Sorry. The current git-Version does not fix the bug, but seems to give empty data and textStatus:
> Safari (page loaded, Safari closed, Safari opened, page loaded again):
> 
> cached1.txt  ifModified: false   error     data: -      jqXHR.responseText: ok     textStatus: 
> cached1.txt  ifModified: false   error     data: -      jqXHR.responseText: ok     textStatus: 
> online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
> online1.txt  ifModified: false   success   data: ok     jqXHR.responseText: ok     textStatus: success
> cached2.txt  ifModified: true    error     data: -      jqXHR.responseText: ok     textStatus: 
> cached2.txt  ifModified: true    error     data: -      jqXHR.responseText: ok     textStatus: 
> online2.txt  ifModified: true    success   data: ok     jqXHR.responseText: ok     textStatus: success
> online2.txt  ifModified: true    success   data: -      jqXHR.responseText: -      textStatus: notmodified
> 
That was fast. :-) The patch fixes the browser differences for the cases with ifModified=false. The differences found with ifModified=true remain as above. Replying to [comment:4 jaubourg]: > blabber, can you confirm this fixes your issue?

I'm confused as to what you say here. What is fixed? What isn't fixed?

Would also help a bunch if your log lines were a bit more compact and featured the status code and error message. For instance:

cached1.text(true/false): statusCode, status (thirdParameterOfErrorCallbackIfError), data, jqXHR.responseText

This would definitely help me tackle this while not having to duplicate your effort.

Changed February 08, 2011 10:08AM UTC by blabber comment:9

This bug probably collects a number of differences in the way that browsers react to ajax request on files from the ApplicationCache and files from the network. The list in the original bug report gives the complete picture across a number of browser.

At least the different browser reactions to request with ifModified == true should be fixable, because the browsers provide all necessary information. I have provided a simple patch in the original bug report. I have no idea, if it is correct, but it works for my current project (giving success for all cases where ifModified == false).

There are more different cases, when ifModified == false, but I do not even know for sure, how jQuery should react in these cases.

Here are my current test results, Run 1 is identical for the current trunk and jQuery 1.5.

Run 1: Safari startet __without__ test page in ApplicationCache:

   File         ifMod  callback  status  data  respTxt  textStatus   errorThrown
1  cached1.txt  false  success   200     ok    ok       success
2  cached1.txt  false  success   200     ok    ok       success
3  online1.txt  false  success   200     ok    ok       success
4  online1.txt  false  success   200     ok    ok       success
5  cached2.txt  true   success   200     ok    ok       success
6  cached2.txt  true   success   200     ok    ok       success
7  online2.txt  true   success   200     ok    ok       success
8  online2.txt  true   success   304     -     -        notmodified


Run 2: Safari startet __with__ test page in ApplicationCache:

jQuery Trunk 534dbd660eaefbbc5827b1b61ba384e768562086
   File         ifMod  callback  status  data  respTxt  textStatus   errorThrown
1  cached1.txt  false  error     0       -     ok               
2  cached1.txt  false  error     0       -     ok               
3  online1.txt  false  success   200     ok    ok       success
4  online1.txt  false  success   200     ok    ok       success
5  cached2.txt  true   error     0       -     ok               
6  cached2.txt  true   error     0       -     ok               
7  online2.txt  true   success   200     ok    ok       success
8  online2.txt  true   success   304     -     -        notmodified

jQuery 1.5
   File         ifMod  callback  status  data  respTxt  textStatus   errorThrown
1  cached1.txt  false  success   304     -     ok       notmodified
2  cached1.txt  false  success   304     -     ok       notmodified
3  online1.txt  false  success   200     ok    ok       success
4  online1.txt  false  success   200     ok    ok       success
5  cached2.txt  true   success   304     -     ok       notmodified
6  cached2.txt  true   success   304     -     ok       notmodified
7  online2.txt  true   success   200     ok    ok       success
8  online2.txt  true   success   304     -     -        notmodified

index.html, other files as described above:

<html manifest="cache.manifest">

<head>
	<script src="jquery.js"></script>
</head>

<body>
<pre id="log">
   File         ifMod  callback  status  data  respTxt  textStatus   errorThrown
</pre>

<script>
function log(text) { $('#log').append(text + '<br>'); };

var i = 0;
var urls = ['cached1.txt', 'online1.txt', 'cached2.txt', 'online2.txt'];
function test() {
	if (i > 7)
		return;

	load(urls[Math.floor(i / 2)], i < 4 ? false : true);
	++i;
};

function load(url, ifModified) {
	$.ajax({
		dataType: 'text',
		ifModified: ifModified,
		url: url
	}).success(function(data, textStatus, jqXHR) {
		log(i + '  ' + url + '  ' + (ifModified ? 'true  ' : 'false ') + ' success   ' + jqXHR.status +
			'     ' + (data === url + 'x' ? 'ok ' : (!data ? '-  ' : 'err')) +
			'   ' + (jqXHR.responseText === url + 'x' ? 'ok ' : (!jqXHR.responseText ? '-  ' : 'err')) +
			'      ' + textStatus);
		if (jqXHR.responseText && jqXHR.responseText !== url + 'x')
			log('responseText: ' + jqXHR.responseText);
	}).error(function(jqXHR, textStatus, errorThrown) {
		log(i + '  ' + url + '  ' + (ifModified ? 'true  ' : 'false ') + ' error     ' + jqXHR.status +
			'       -  ' +
			'   ' + (jqXHR.responseText === url + 'x' ? 'ok ' : (!jqXHR.responseText ? '-  ' : 'err')) +
			'      ' + textStatus + '        ' + errorThrown);
		if (jqXHR.responseText && jqXHR.responseText !== url + 'x')
			log('responseText: ' + jqXHR.responseText);
	}).complete(function () {
		test();
	});
};

$(document).ready(function() {
	window.setTimeout(test, 1000);
});

</script>

</body>
</html>

Changed February 11, 2011 06:13AM UTC by jaubourg comment:10

blabber, status for local files should always be 200 now. Be aware that empty files will trigger an error (that's due to some serious limitations in native xhr implementations). Waiting for your confirmation/infirmation.

Changed February 11, 2011 12:11PM UTC by blabber comment:11

Replying to [comment:10 jaubourg]:

blabber, status for local files should always be 200 now. Be aware that empty files will trigger an error (that's due to some serious limitations in native xhr implementations). Waiting for your confirmation/infirmation.

Unfortunately that did not work. I have written a new patch for the current trunk, that tries to handle some of the cases in xhr.js. The patch does not change as much, as it seems to change, but mostly restores old tests and combines them in a slightly different way.

With the patch most browsers seem to work with ifModified = false. Case 6 still differs between browsers or even between access to localhost or access to ip address (for Firefox 3.6.13). Opera also acts chaotic (success with ip, error with localhost, error with ip from virtual machine...). Perhaps all this are just ApplicationCache problems. After all my tests I do not really trust any browser in this regard... ;-)

I will use my patched version of the trunk for now and give further feedback, if I run into any obvious problems, but do not have the time at the moment to do more extensive cross-browser ... tests. :-/

diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js
index 9c8790a..0bad811 100644
--- a/src/ajax/xhr.js
+++ b/src/ajax/xhr.js
@@ -166,14 +166,30 @@ if ( jQuery.support.ajax ) {
 									}
 
 									// Filter status for non standard behaviors
-									status =
-										// If the request is local and we have data: assume a success
-										// (success with no data won't get notified, that's the best we
-										// can do given current implementations)
-										!status && s.isLocal && !s.crossDomain ?
-										( responses.text ? 200 : 404 ) :
-										// IE - #1450: sometimes returns 1223 when it should be 204
-										( status === 1223 ? 204 : status );
+
+									// IE - #1450: sometimes returns 1223 when it should be 204
+									if ( status === 1223 ) {
+										status = 204;
+									// If the request is local and we have data: assume a success
+									// (success with no data won't get notified, that's the best we
+									// can do given current implementations)
+									} else if ( !status ) {
+										// Webkit, Firefox: filter out faulty cross-domain requests
+										if ( !s.crossDomain || statusText ) {
+											// Opera: filter out real aborts #6060
+											if (responseHeaders || xml) {
+												status =
+													!headers[ "if-modified-since" ] && !headers[ "if-none-match" ] ?
+														200
+														: 304;
+											} else {
+												status = 0;
+											}
+										// We assume 302 but could be anything cross-domain related
+										} else {
+											status = 302;
+										}
+									}
 								}
 							}
 						} catch( firefoxAccessException ) {

Changed February 11, 2011 11:25PM UTC by jaubourg comment:12

_comment0: blabber, with current Trunk, you'll always get 200 OK for local files as long as they are not empty. This ii because browser's xhr implementations are completely uninformative when it comes to the file system (no headers, no meaningful status code -- always 0 --, etc). \ \ As of today, there is no mean to differentiate between all the different cases encompassed by a zeroed status code without breaking something, elsewhere, for another browser (and in the case of Opera, for the same browser). \ \ I'll close this as patchwelcome but I don't expect one until browsers fix their many xhr inconsistencies. \ 1297466739934998
milestone: 1.5.11.next
owner: jaubourgblabber

blabber, with current Trunk, you'll always get 200 OK for local files as long as they are not empty. This is because browser's xhr implementations are completely uninformative when it comes to the file system (no headers, no meaningful status code -- always 0 --, etc).

As of today, there is no mean to differentiate between all the different cases encompassed by a zeroed status code without breaking something, elsewhere, for another browser (and in the case of Opera, for the same browser).

I'll close this as patchwelcome but I don't expect one until browsers fix their many xhr inconsistencies.

Changed February 11, 2011 11:25PM UTC by jaubourg comment:13

resolution: → patchwelcome
status: assignedclosed

Changed February 14, 2011 01:49PM UTC by blabber comment:14

Replying to [comment:12 jaubourg]:

blabber, with current Trunk, you'll always get 200 OK for local files as long as they are not empty.

I am not talking about local files, but about the ApplicationCache. That may be local, but is probably not handled the same way as local files. Have you changed the trunk again, to really return 200 Ok for all files from the application cache? If not, my test results from above are probably still valid. The last time I checked the trunk, the results where worse than in 1.5, because the request returned an error instead of success.

I'll close this as patchwelcome but I don't expect one until browsers fix their many xhr inconsistencies.

I have provided 2 patches, one for the trunk and one for 1.5, that let the browsers return 200 Ok for files from the application cache. Did you use the information from these patches, to fix the problems? Did you setup the test case? If not: How can I help? What is wrong with my fixes? Did I miss any important points?

I am really trying to help...

Changed February 21, 2011 04:42PM UTC by jaubourg comment:15

@blabber,

I'm all for fixing bugs, believe me, but your patch worked only because of a very serious bug in 1.5 that made any failing ajax request from the local filesystem (and apparently Application Cache) issue a 304.

The situation with the native xhr status set to 0 with no mean to determine if it is a success or an error makes it impossible to lay out any kind of consistant logic that wouldn't break something elsewhere.

If the Application Cache issues a 0 status-code in a non local filesystem environment then we just can't assume it is a 200 OK: this would basically break every other environment.

Like I said, it's patch-welcome but I'm sorry to say it's probably up to the browsers' developpers at this point... and from what I've seen the last few months, I don't believe adding consistency to their xhr implementations to be a priority... which incidently happens to turn my life into a nightmare.

Changed May 02, 2011 08:50PM UTC by chrelad@gmail.com comment:16

I am also seeing this problem. When I make a request for a resource that is in the ApplicationCache, I receive "success" the first time with the data being passed to the "success" callback. It even works if I hit refresh a bunch of times, but when I close the browser (android) and start it again; I get "notmodified" as the status text and "undefined" as the data.