Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

'Error loading page' when opening a page specified in appcache manifest (iPhone) #1579

Closed
jammus opened this issue May 6, 2011 · 46 comments
Closed

Comments

@jammus
Copy link

jammus commented May 6, 2011

Supporting files: https://gist.github.com/959332

Steps to reproduce:

Open index.html on iPhone.
Click add to home screen.
Click on newly created icon.
Browse to 'read more'.

What should happen:

Otherpage.html should be loaded from the appcache.

What happens instead:

'Error loading page'.

Some googling has turned up this diagnosis from Stackoverflow: http://stackoverflow.com/questions/5824549/cannot-access-manifest-cached-files-with-ajax-from-webapp-saved-to-home-screen-in

"Apparently, when trying to use $.ajax() in offline mode, the request successfully fetches the cached files, but it returns 0 on XHMLHttpRequest.status. Having read up on this, I have seen that a status code of 0 can be returned when the user is offline and even when requesting local files. However, a successful GET should report a status code between 200 and 300. Perhaps $.ajax() checks for a 200-300 status, otherwise the request is considered to have failed."

Checking the value of jqXHR.responseText in the error handler of the ajax request shows the contents of otherpage.html.

The same issue also appears to affect Android (2.2 tested).

@jblas
Copy link
Contributor

jblas commented May 6, 2011

@jammus

What version of jQuery Core and jQuery Mobile are you using?

@jammus
Copy link
Author

jammus commented May 6, 2011

Sorry, my bad. jQuery 1.6 and jQM was built from master some time this morning.

@jblas
Copy link
Contributor

jblas commented May 6, 2011

@jammus: There were some problems with loading local files this morning that we've since fixed. Can you update and try the newer source?

@jammus
Copy link
Author

jammus commented May 6, 2011

@jblas: Sure thing. Done and reset the simulator - still getting the same issue on the iPhone. (Can't retest Android at the moment)

@jammus
Copy link
Author

jammus commented May 10, 2011

@jblas: Finally managed to retest on Android - still experiencing the same issue.

@jcorporation
Copy link

This is the same issue and the patch provided works for me with offline manifest
#926

@jammus
Copy link
Author

jammus commented May 13, 2011

@jcorporation: Thanks for the info. The issue is certainly similar. However the success callback isn't firing for me, only the error callback.

The line mentioned in the other ticket has since changed though so it maybe I'm looking in the wrong place.

@jcorporation
Copy link

Right, the line changed, you should try the patch. My symptom was an endless loading message.

@jammus
Copy link
Author

jammus commented May 14, 2011

The symptom here is the yellow 'Error loading page' message. The patch won't work in this case as the success callback of the ajax request in changePage is not called when loading a page stored in the appcache.

@hakanson
Copy link
Contributor

Looks similar to jQuery bug #8412. I wonder if an ajax prefilter that treats offline like other local protocols would work?

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
  // treat offline like file: protocol
  if ( navigator.onLine && navigator.onLine === false ) {
    options.isLocal = true;
  }
});

Here is a snippet of the jQuery ajax code that would get triggered when isLocal is true and status is 0.

// 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)
if ( !status && s.isLocal && !s.crossDomain ) {
    status = responses.text ? 200 : 404;

@jammus
Copy link
Author

jammus commented May 16, 2011

@hakanson Thanks for the link. That appears to be the exact issue we're experiencing.

The prefilter looks like a potential solution. I don't think navigator.onLine is the suitable value to check though as the appcache can be used even if the device is online. Under iOS navigator.standalone, which indicates if the site has been launched as a web app, is a better option. Not sure it's ideal though as there may be other circumstances where the appcache is hit.

@jammus
Copy link
Author

jammus commented May 16, 2011

Maybe applicationCache.status is a candidate. If it's not set to UNCACHED or OBSOLETE then apply the filter.

@hakanson
Copy link
Contributor

Is this the same issue as #1194 from @mfkahn ? That also refers to jQuery bug #8412.

@hakanson
Copy link
Contributor

If appcache can be used when online, then navigator.onLine won't work.

Also, if appcache can be used either from Mobile Safari or if "webpage is displayed in full-screen mode" (Hiding Safari User Interface Components), then navigator.standalone won't work.

I agree that some property of DOMApplicationCache like applicationCache.status is better.

@jammus, can you try out an ajaxPrefilter and see if it works?

@jammus
Copy link
Author

jammus commented May 20, 2011

@hakanson Sure. After adding the following the 'error loading page' error is no longer shown and all pages load fine.

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (applicationCache &&
            applicationCache.status != applicationCache.UNCACHED &&
            applicationCache.status != applicationCache.OBSOLETE
        ) {
        options.isLocal = true;
    }
});

@jammus
Copy link
Author

jammus commented May 20, 2011

Actually, it might not be working perfectly. Going back to it now I'm getting the same error as before but not every time. I'll do some more digging.

@mfkahn
Copy link

mfkahn commented May 31, 2011

See http://bugs.jquery.com/ticket/8412 , someone has posted a workaround that uses the 1.5.1+ isLocal setting for ajax. Seems to fix the issue, at least on iOS, I did not check android.

@jammus
Copy link
Author

jammus commented May 31, 2011

As a follow up to my previous comment the resurfacing of the error was due to entirely different issue so I'm now confident that the above fix works.

@mfkahn Thanks for the update. We earlier debated the use of navigator.standalone, however as the cache manifest can also be used in browser mode we weren't sure it was entirely suitable. Maybe the workaround should include both. I'll cross post to that ticket and see if anyone has more input.

@mfkahn
Copy link

mfkahn commented Jun 1, 2011

If it helps - on that ticket (http://bugs.jquery.com/ticket/8412) I had posted a link to the same issue I'd logged to ADC. The ADC issue report contains an example that can be used to demonstrate the issue. When I add the isLocal fix to the example the app works the same in both modes (web-app/browser). I was surprised, from reading the jquery docs I had assumed the isLocal setting would have fixed the items in the CACHE section but broken items in the NETWORK section, but it seems fine.

@toddparker
Copy link
Contributor

Just following up here...is this still an open issue?

@ksksks
Copy link

ksksks commented Aug 29, 2011

This issue is still not solved and is a big problem.
Sites using ajax for loading stop working when a cache manifest is defined.
Wether the prefilter

$(document).ready(function () {
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        options.isLocal = true;
    });
});

nor a plain

$(document).ready(function () {
    jQuery.ajaxSetup({isLocal:true});
});

works for me on Android (GalaxyTab v2.2, Defy v2.3) or in Firefox 6.0.

@ghost ghost assigned jblas Sep 22, 2011
@toddparker
Copy link
Contributor

Just bumped up the priority here since it sounds like it's still unresolved.

@johnbender
Copy link
Contributor

Doing my best to get caught up here and I have a few questions (bear with me):

@jammus

In your snippet

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (applicationCache &&
            applicationCache.status != applicationCache.UNCACHED &&
            applicationCache.status != applicationCache.OBSOLETE
        ) {
        options.isLocal = true;
    }
});

won't this treat any and all requests as file system requests even when they aren't request to the cache or file system so long as the app cache is valid? So if the user is online, the cache is valid, and he/she makes a request for a page not listed in the manifest it really should be requested as normal (ie not isLocal). Again, I'm just eyeballing it so if I'm off course you'll have to forgive me.

@hakanson and @ksksks I would ask the same of both:

$(document).ready(function () {
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        options.isLocal = true;
    });
});

and

$(document).ready(function () {
    jQuery.ajaxSetup({isLocal:true});
});

isLocal appears to make sense when you can verify that the user cannot make web requests and should only be able to retrieve the material from the cache. If you look at the jquery xhr handling the reason this seems to work is that, right now, it only really cares about isLocal for coercing the status into something sane when the value is 0 and not cross domain.

https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js#L167

@ghost ghost assigned johnbender Oct 12, 2011
@johnbender
Copy link
Contributor

This is also probably a good place to note for people who read the above and want to use the workaround that if the request is cross domain it won't work. See (which @hakanson linked earlier):

https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js#L167

@johnbender
Copy link
Contributor

[edit] answered my own question with a simple test.

@jammus
Copy link
Author

jammus commented Oct 13, 2011

Hi @johnbender,

Yeah, you're right. It treats all requests as local when a cache exists. As you point out though it is a bit of a hack. Maybe the check or one similar should be pushed into xhr.js in jQuery main rather than relying purely on isLocal behaving this way forever.

Cheers,
James

@johnbender
Copy link
Contributor

Another quick update here:

http://dev.w3.org/html5/spec/offline.html#appcache

It looks like the manifest entries have to come from the same origin so my comment about cross domain requests not working shouldn't be an issue. I think the fact that isLocal really has nothing to do with the problem might prove dangerous since it could be used for other purposes in core.

tl;dr this will remain the workaround

@mfkahn
Copy link

mfkahn commented Nov 24, 2011

Has anyone identified this an issue on any platforms except iOS running in navigator.standalone=true mode?

@aiwilliams
Copy link

I'm using the isLocal workaround.

I have index.html linking to welcome.html, welcome.html?v=1, and welcome.html?v=2. When I click on the first two, all's well! welcome.html is in the cache, and loads just fine, and my javascript can access the query param as undefined and 1, respectively. Yet when I click the third link, the xhr.status is 0, but the response.text is empty - therefore jQuery interprets this as a 404, and page load fails.

Why in the world would the first two links work fine, but not the third?

If I flip $.mobile.ajaxEnabled = false, then all three links work fine from the cache, but of course I lose page transitions.

This issue occurs in Safari 5.1.2. Chrome works fine, where any variance in query params still successfully loads welcome.html!

@jammus
Copy link
Author

jammus commented Dec 16, 2011

@aiwilliams Do you have all three page in the cache manifest?

@aiwilliams
Copy link

No, I was not thinking of the v=1, v=2 as being separate pages, but I can see now that they are indeed treated that way by the cache mechanism. This seems to explain why $.mobile.ajaxEnabled = false causes the links to work, since each of the two query param urls would cause a fetch to the server. There are so many things to keep up with! I think I'm good to go.

@toddparker
Copy link
Contributor

Sounds like we can close this issue then?

@jammus
Copy link
Author

jammus commented Dec 17, 2011

@toddparker No, I don't think so. The original issue reported is different to the one @aiwilliams mentions here. At least as far as I understand.

@johnbender
Copy link
Contributor

@toddparker

I concur with @jammus. We really want to leave this one open to signal to devs that it's still an outstanding issue and they need to use the workaround.

@toddparker
Copy link
Contributor

Ok, sounds like a plan.

@mattberg
Copy link

mattberg commented Mar 5, 2012

I recently came across this issue running Android 2.3.6. Any local pages just linked with index.html, about.html, dir/index.html all returned "Error loading page" when pulling from appcache.

So you have to choose between ajax and nice page transitions and offline capability? Seems like a pretty major issue right?

@nimy
Copy link

nimy commented Apr 17, 2012

I got offline cache downloading problem in Opera Mobile, it is not caching the files. Also getting window.applicationCache.status as always '0', when the 'turbo' setting is 'ON'. Unfortunately html5 storage (webSQL) is not working with 'turbo' 'OFF'. I need both (html5 offline caching & storage) to run my jQuery mobile application. Please help me.

@PlippiePlop
Copy link

This issue is still open with JQmobile 1.1 final and jQuery1.7.1

when using ajax for page navigation on Apple Iphone devices launching from homescreen (web-app)
It shows a error popup a second but continues to next page.

@mdempfle
Copy link

mdempfle commented May 8, 2012

I can confirm this.
I have played around with different browsers and is seem that at the desktop Firefox and Chrome work fine. Also Opera on Android. It fails in the native browser of android 2.3.4 and Dolphin, Dolphin HD.

My current workaround is to use rel="external" for links.

So I agree with mattberg that this i a pretty major issue.

So is there a workaround where at least the ajax capability is not lost?

@justechn
Copy link

justechn commented Jul 2, 2012

I am experiencing the same issue. Has a workaround or fix been developed for this? I am using JQM 1.1.0 and JQ 1.7.1, and I am all on the same domain.

@frequent
Copy link
Contributor

I'm also in the boat, although I don't use appache/manifest at all and still get the behavior described above.

@ryanilg
Copy link

ryanilg commented Sep 14, 2012

Also having this issue, running 1.2.0-alpha with jQuery 1.7.2

@m-vdv
Copy link

m-vdv commented Nov 21, 2012

Can confirm this issue still exists.

Tested today on iPhone 5 (iOS6).
Exact same issue as @PlippiePlop

"Error Loading Page" shows for a second but the page does load.
Only happens when launching webapp from homescreen, works correct in safari.
Latest JQM version (1.2)

@m-vdv
Copy link

m-vdv commented Nov 21, 2012

Currently I'm using this CSS snippet to move the error message out of screen:

.ui-loader.ui-body-e {
left:-9999px !important;
}

This is obviously far from perfect, but seems to be the only way to get rid of the error message within an iOS WebApp.

There's no loading image either so UX wise the user doesn't know a new page is loading..
(except for the tiny spinner in the iOS top bar)

Anyone with a proper solution, please share ;)

@ldeluca
Copy link
Contributor

ldeluca commented Oct 21, 2014

hey everyone, no updates on this issue in over 2 years. Is it still valid? @jammus ?

@arschmitz
Copy link
Contributor

Im guessing this is no longer an issue since there are no new reports if someone is still having this issue with latest code comment and we will reopen im going to close this as stale.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests