Side navigation
#8412 closed bug (wontfix)
Opened March 01, 2011 01:13PM UTC
Closed March 10, 2011 01:07AM UTC
Last modified January 04, 2013 08:34PM UTC
Ajax problem on iOS with HTML5 applicationCache and web-app mode
Reported by: | mfkahn@gmail.com | Owned by: | mfkahn@gmail.com |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | unfiled | Version: | 1.5.1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
This may not be a jQuery bug, however without a workaround it will affect projects such as jQuery mobile and adoption of jQuery in HTML5 apps.
On iOS (iphone/ipad etc), when a $.get is done for a resource that has been cached in the HTML5 applicationCache (applicationCache.status == 1), *and* the application is running in "web-app" mode (where the <meta name="apple-mobile-web-app-capable" content="yes"> is present in the main page, as opposed to normal "safari"/browser mode), the http status of a successful request will be set to 0 (zero), not 200.
This forces the jQuery error handler to be called. We have had to work around this by using a low-level XmlHttpRequest instead of the jquery ajax object (not just in 1.5.1, this has been an issue for a while). It might be a significant issue for developer usability on iOS, esp for jQueryMobile. Not sure if there is a bug logged at ADC about this or not.
Steps to reproduce:
- create an HTML5 app with a cache-manifest file, using an index.html page with the <meta name="apple-mobile-web-app-capable" content="yes"> tag.
- create a second something.html file, listing it in the CACHE section (or default section) of the manifest
- onReady (or whenever), do a $('#something').load('something.html').
- try this on any compatible desktop browser (safari, chrome, firefox) - should Works
- try this on iOS safari (iPad/iPod) - should work
- in iOS/safari, click "bookmark", then "add to home screen". Go to the device home screen and launch the app in full screen mode by tapping the tile. - won't work, the content won't be loaded and if you attach an error handler you'll see the http status from the xhr was 0, but the correct content was returned (last reproduced in iOS 4.1.2 on iPad).
Attachments (0)
Change History (16)
Changed March 01, 2011 09:35PM UTC by comment:1
owner: | → mfkahn@gmail.com |
---|---|
priority: | undecided → low |
status: | new → pending |
Changed March 02, 2011 06:50AM UTC by comment:2
You could try and set the isLocal global ajax settings to true in that case:
jQuery.ajaxSetup({ isLocal: true });
These environment where every request, successful or not, always return a 0 status code are, simply put, impossible to deal with in a general fashion (if we fix for them, we break all the others). So, until the devs behind these totally absurd xhr implementations get back to their senses, I'm afraid there will be some need for trickeries on the part of users, sadly. ;)
Changed March 02, 2011 12:15PM UTC by comment:3
Thanks for the feedback - I have sent the issue to ADC as well, but no reply yet.
Changed March 05, 2011 06:33PM UTC by comment:4
This has been logged to apple as ADC bug # 9092131
There is a working example attached in a zipfile that demonstrates the issue.
Changed March 10, 2011 01:07AM UTC by comment:5
resolution: | → wontfix |
---|---|
status: | pending → closed |
OK, so we'll wait and see if and when this is fixed in iOS.
Changed March 14, 2011 06:59PM UTC by comment:6
mfkahn, do you have a work-around that you could share? We're hitting the wall on this issue too.
Changed March 14, 2011 07:52PM UTC by comment:7
No, sorry. We've been using two design-around approaches:
1) low-level XMLHttpRequest, when we're certain the resource will be cached properly and absolutely must AJAX load it
2) using navigator.onLine detection and storing resources fetched with $.ajax while online in the localStorage, thereby avoiding the $.ajax call altogether when offline. This actually works better anyways since you can re-use dumbed-down, more generic manifest files for multiple pages that need to work offline.
I have cross-reported this bug to the jQuery Mobile team, I think this will be worth looking into for them, its a pretty nasty issue to support and explain to users.
Changed March 23, 2011 06:51PM UTC by comment:8
Here is the update from ADC on this issue, who claim the behaviour is correct according to the HTML5 spec, and so they do not intend to fix. So I think this should be re-opened as a jQuery core bug, as nobody will be able to use jQuery or jqMobile to write ajax apps for iOS or any other device else that interprets the spec in this way.
Hi,
This is a follow-up to Bug ID# 9092131.
Engineering has determined that this issue behaves as intended based on the following information:
This is the correct behavior. In offline mode, there is no actual HTTP request being made, so it would be incorrect to report a status as if there was one. For this to change, we'd have to get this behavior written into the appropriate spec (ie: HTML5).
Changed May 30, 2011 10:50PM UTC by comment:9
There's a very simple solution for this. Add this to your DOM "ready" event function:
if (window.navigator.standalone) jQuery.ajaxSetup({isLocal:true});
Changed May 31, 2011 01:01AM UTC by comment:10
The fix works on iOS, not certain if there is any effect on other platforms. NETWORK: sections in a cache manifest still load properly too.
Thanks for isLocal in jQuery 1.5.1!
Changed May 31, 2011 09:19AM UTC by comment:11
A similar issue is being discussed on jQueryMobile. One possible problem with the workaround posted is that the appcache can be used when not in standalone mode (at least as far as I understand) therefore a check for navigator.standalone might not be sufficient. Has anyone else experienced the issue when in browser mode?
jqm ticket: https://github.com/jquery/jquery-mobile/issues/1579#comment_1264369
Changed October 24, 2011 07:31PM UTC by comment:12
I am experiencing a similar problem, which has had me stumped for days. I am working with jQuery 1.6.4, on an iPad 1, using Safari on iOS 5.0. I have set up my app to be stored in the application storage on the iPad. However, I have a number of Ajax calls which must get information from PHP on the web server, information that cannot be cached on the device. When the app runs on any of the desktop browsers, including Safari on Windows 7 emulating an iPad running Safari iOS 4.3.3, it works as expected. However, on the iPad, it does not.
When I check the web server system logs, the iPad is not issuing an Ajax call (using $.ajax()) to the server. I am getting status = 0, as mentioned in other notes on this ticket, but with an empty string for responseText (which I assume is because the PHP file in question is not on the local device.
Changed January 13, 2012 04:59AM UTC by comment:13
I encounter the similar problem, but I have solved it by adding the following to the manifest file, see if this could apply to your case
NETWORK: *
Changed May 31, 2012 01:35AM UTC by comment:14
As mentioned on http://stackoverflow.com/questions/5824549/, you can also test jqXHR.responseText in the error handler to see if there was a response. When I design using applicationCache, I now routinely just test the jqXHR.responseText in the case that status==0 (which it will when the files are fetched from the cache).
Changed November 25, 2012 04:41AM UTC by comment:15
Adding the NETWORK wildcard also worked for me on FireFox 16.0.2. This is weird behavior for sure.
Changed January 04, 2013 08:34PM UTC by comment:16
Replying to [comment:15 anonymous]:
Adding the NETWORK wildcard also worked for me on FireFox 16.0.2. This is weird behavior for sure.
I too ran in to this today, had been fighting it for hours. Once I managed to get the manifest to update in Chromium things started working as expected.
Thanks for submitting a ticket to the jQuery Bug Tracker.
With respect to us evaluating this particular issue, are you able to supply us with a test case (either on jsFiddle or probably more suitably in this scenario a zip/attachment incl cache manifests) that demonstrates what you've reported?
If so, this would greatly decrease the amount of time before we're able to confirm whether or not this is an issue we may address with jQuery core.