Search code examples
jquery-mobilephonegap

jQueryMobile+PhoneGap+iOS 11: Blocked attempt to use history.replaceState() to change session history URL


Starting with iPhone OS 11.3, my app is broken with the following error:

SecurityError: Blocked attempt to use history.replaceState() to change session history URL from file:///var/containers/Bundle/Application/E73A3E4A-D961-4943-BAA3-7845E755F6A0/myplaceonline.app/www/index.html#/?phonegap=true to https://myplaceonline.com/?phonegap=true. Protocols, domains, ports, usernames, and passwords must match.
url:
file:///var/containers/Bundle/Application/E73A3E4A-D961-4943-BAA3-7845E755F6A0/myplaceonline.app/www/js/jquery.mobile-1.4.5.min.js
line #: 3 (31672)

The way I've always done it (and this continues to work with Android):

  1. PhoneGap app loads JQM in an index.html page.
  2. A JQM mobileinit event handler is attached which registers a pageloaded event handler which ultimately calls loadHomepage.
  3. loadHomepage sets $.mobile.path.documentBase and the href attribute of the base tag to my remote server (https://myplaceonline.com/) and calls $.mobile.pageContainer.pagecontainer("change", "/", { allowSamePageTransition: true, transition: 'none', reloadPage: true, changeHash: true }); to load the remote homepage.
  4. This ultimately drives JQM to call replaceState which fails with the security error: replaceState@[native code] squash@file:///var/containers/Bundle/Application/E73A3E4A-D961-4943-BAA3-7845E755F6A0/myplaceonline.app/www/js/jquery.mobile-1.4.5.min.js:3:31672 go@file:///var/containers/Bundle/Application/E73A3E4A-D961-4943-BAA3-7845E755F6A0/myplaceonline.app/www/js/jquery.mobile-1.4.5.min.js:4:322 navigate@file:///var/containers/Bundle/Application/E73A3E4A-D961-4943-BAA3-7845E755F6A0/myplaceonline.app/www/js/jquery.mobile-1.4.5.min.js:4:1598

The purpose of all of the above is so that I don't navigate away from file:/// because if I were to do that, I would lose access to all native phone JS APIs through PhoneGap. This works on older versions of iOS and continues to work on Android.

Any ideas on an alternative way to do this to get around the tighter security on newer versions of iOS? Alternatively, I see there are issues like https://github.com/jquery/jquery-mobile/issues/5465 which suggest a method of disabling history and I'm wondering if this would be another workaround and what I would lose?


Solution

  • Adding the following code to a mobileinit handler fixes the issue:

    $.mobile.hashListeningEnabled = false;
    $.mobile.pushStateEnabled = false;
    $.mobile.changePage.defaults.changeHash = false;