Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS9, Chrome, react router examples - history not working properly #2565

Closed
kellyrmilligan opened this issue Nov 18, 2015 · 44 comments
Closed
Labels

Comments

@kellyrmilligan
Copy link
Contributor

Creating a new issue for testing on iOS9 on Chrome, I cloned the repo and ran the examples and the history implementation is not working as expected. Steps:

  • from React Router examples, click on Master Detail
  • click on a name on the list on the left
  • click on the back button in chrome

The browser goes back all the way to the examples list, and not the first page of the master detail example as it does in desktop browsers.

mobile safari is working as expected. This must be something with the webview that chrome is using I suspect.

@taion
Copy link
Contributor

taion commented Nov 18, 2015

Sounds like potentially the HTML5 history API doesn't work with Chrome on iOS then - @mjackson do you think this could be a hole in the feature-sniffing code we borrowed from Modernizr?

@kellyrmilligan
Copy link
Contributor Author

It does navigate forward just fine

@timdorr
Copy link
Member

timdorr commented Nov 18, 2015

I'll whip out my iPad tonight to confirm. It's likely something in history, so expect a PR with fixes there.

@timdorr timdorr added the bug label Nov 18, 2015
@taion
Copy link
Contributor

taion commented Nov 18, 2015

My suspicion is that iOS Chrome is doing something wonky when you hit the back button (i.e. not doing the proper pop state but actually doing a hard reload). This would suggest that we should treat iOS Chrome as if it didn't support HTML5 history.

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

Confirmed on my iPad just now. I get navigated back to the root and going forward goes back to the detail view I clicked on. I'm going to do some ugly debugging since I don't have a console...

@taion
Copy link
Contributor

taion commented Nov 19, 2015

Do you think that's our bug, though? I don't think there's anything we can do on our side to control what the browser's back button does, besides just not using the history API and instead using hard transitions everywhere.

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

Dunno, but I figure I might as well do some basic stuff and see what happens.

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

Oh, check it out. Chrome iOS actually rewrites history.pushState as this funky thing:

function(b, d, c) {
    __gCrWeb.message.invokeOnHost({
        command: "window.history.willChangeState"
    });
    d = "undefined" == typeof b ? "" : __gCrWeb.common.JSONStringify(b);
    c = c || window.location.href;
    f.call(history, b, "", c);
    a({
        command: "window.history.didPushState",
        stateObject: d,
        baseUrl: document.baseURI,
        pageUrl: c.toString()
    })
}

Without seeing the whole context, I don't know exactly what's going on here.

Interestingly, if you go directly to http://1.2.3.4:8080/master-detail/ in Chrome and start navigating around, it appears that pushState works fine. Maybe this is a non-issue for normal apps?

In any case, I would handle it the same way as with IE9 or IE8 support and switch out to a hash history. This would appear to be a bug with Chrome iOS, so it's not something we can solve on our end, unfortunately.

@timdorr timdorr closed this as completed Nov 19, 2015
@taion
Copy link
Contributor

taion commented Nov 19, 2015

@timdorr What happens with iOS Chrome on other SPAs that use the HTML5 history API? Does hitting the back button also result in the same behavior noted here?

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

It appears to work fine with some pushState examples I've found on the web. I'm not sure what's triggering it, but it's pretty likely a Chrome-specific bug.

@kellyrmilligan
Copy link
Contributor Author

So the recommendation is to sniff the user agent then for this to switch between history and whichever alternative?

@kellyrmilligan
Copy link
Contributor Author

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

I would test an actual usage against Chrome iOS, not just the example code. It appears to work fine for me with normal apps. It's really a Chrome bug for not being compliant with the spec.

@kellyrmilligan
Copy link
Contributor Author

Yes this issue was raised after I tested my app with 13.3. Since hat is no longer being developed, I chose to test with he examples which have the same issue. I'm going to conditionally set my history type, so at least for now I'll have a spa back in most places.

@taion
Copy link
Contributor

taion commented Nov 19, 2015

Wait - if iOS Chrome doesn't fully support HTML5 history, it's our responsibility to make createBrowserHistory fall back to full page refreshes. That said, it does look like there's some instability in the history impl for iOS Chrome: https://code.google.com/p/chromium/issues/detail?id=483709.

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

@taion It's not that they don't support it, it's that their implementation is buggy.

@taion
Copy link
Contributor

taion commented Nov 19, 2015

Yup - and we have code like https://github.com/rackt/history/blob/v1.13.1/modules/DOMUtils.js#L50-L53 exactly to deal with buggy History impls.

@kellyrmilligan
Copy link
Contributor Author

I'd add crios to that from the link above

@taion
Copy link
Contributor

taion commented Nov 19, 2015

@kellyrmilligan @timdorr If this is legitimately a CriOS bug, we should file something on the Chrome iOS issue tracker. It'd be ideal not to keep around an exception for an actively-maintained browser indefinitely.

@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

I put in a PR on history.

@taion I agree. I would expect us to either a) discover the exact conditions causing the bug and apply a workaround or b) Google fixes it upstream and everything starts working again.

@taion
Copy link
Contributor

taion commented Nov 19, 2015

This looks like a bug on our end. http://html5demos.com/history works fine on CriOS. Our examples do not.

@taion
Copy link
Contributor

taion commented Nov 19, 2015

Poked at this for a bit and couldn't figure out what was wrong with createBrowserHistory. I'm going to re-open this issue though, because other examples of using HTML5 history on Chrome seem to work.

@taion taion reopened this Nov 19, 2015
@timdorr
Copy link
Member

timdorr commented Nov 19, 2015

@taion No, it is not. Chrome iOS has a buggy implementation that does not comply with the spec. Others have had this same issue: devote/HTML5-History-API#29

If you go directly to the master-detail example (http://1.2.3.4:8080/master-detail/), you'll find that our implementation works fine. It's not impossible to make it work, but it doesn't look like something we can solve without some ugly, browser-specific hacks.

For now, just disabling support on Chrome iOS is the best option.

@taion
Copy link
Contributor

taion commented Nov 19, 2015

I found the same old bugs with pushState being broken, but those seemed unrelated.

Can you take a look at http://html5demos.com/history when you get a chance on Chrome iOS and let me know if it works for you?

@kellyrmilligan
Copy link
Contributor Author

That Demo is working for me in crios on iOS 9

@taion
Copy link
Contributor

taion commented Nov 20, 2015

@timdorr Ah, you're probably right - I don't think any of us have time to fix this right now, and there's no point tracking an issue we're not actively working on, especially in the wrong repo, when we have a workaround. Going to re-close then.

@taion taion closed this as completed Nov 20, 2015
@kniknak
Copy link

kniknak commented Jan 15, 2016

Caught this bug on CriOS latest react-router 1.0.3 + history 1.17.
Then I went back to 1.0.2 and 1.13.1. It works well

@mhart
Copy link

mhart commented Jan 15, 2016

Also seeing pushState-based actions with react-router not working on Chrome iOS w/ history 1.17

What's the best way to mitigate this currently?

@taion
Copy link
Contributor

taion commented Jan 15, 2016

Wait – pushState isn't working?

@mhart
Copy link

mhart commented Jan 15, 2016

Right – history doesn't work at all thanks to this: https://github.com/rackt/history/blob/v1.17.0/modules/DOMUtils.js#L57-L61

I've just tried commenting that check out, and everything seems to work fine for us. You sure that Chrome iOS hasn't fixed whatever issues you were seeing back in the day?

@mhart
Copy link

mhart commented Jan 15, 2016

@taion I'm happy to open an issue at https://github.com/rackt/history if you want – just that code linked to here.

@taion taion reopened this Jan 15, 2016
@taion
Copy link
Contributor

taion commented Jan 15, 2016

It doesn't really make life any easier. The issue here was actually with popState transitions.

I'm confused why you wouldn't see it work at all, though – that check should make it fall back to doing full page refreshes rather than "do nothing".

@mhart
Copy link

mhart commented Jan 15, 2016

@taion right, that's what it does – I didn't say it "did nothing" – I said it didn't work. So the whole page refreshes.

This must've changed at some point, because it used to work fine – at least for everything that we do at m.uniqlo.com

I'm going to fork and comment out that check because all our testing indicates that everything in the history API works fine on Chrome iOS.

Is there some test that you've got that doesn't work on Chrome iOS?

@taion
Copy link
Contributor

taion commented Jan 15, 2016

Give me a sec.

@taion
Copy link
Contributor

taion commented Jan 15, 2016

Okay, this issue does seem to have been resolved on the latest CriOS. We're good to drop this check in history, I think – it's more pain than it's worth.

@mhart
Copy link

mhart commented Jan 15, 2016

Cool, thanks – just realised I can't even link to my patched version anyway because it fails the goddamn peerDependencies check from react-router due to npm/npm#3218 ... sigh.

@taion
Copy link
Contributor

taion commented Jan 15, 2016

v1.0.3 is functionally the same as v1.0.2 except for the updated peer dependency, as far as I'm aware.

We should be cutting a v2.0.0-rc3 shortly with this fix anyway for #2859, but if you already have a working setup, there's limited reason to upgrade to v1.0.3 right now.

@mhart
Copy link

mhart commented Jan 26, 2016

history v2.0.0-rc3 still hasn't been released – any ETA on that?

@timdorr
Copy link
Member

timdorr commented Jan 26, 2016

I poked @ryanflorence to poke @mjackson about that yesterday. They've got a lot of work coming up in the next 2 weeks, but I'm hoping they can push out new RCs before then so we can go final when they're back.

@timdorr
Copy link
Member

timdorr commented Jan 27, 2016

I wonder if this is fixed by CriOS's switch to WKWebView? http://blog.chromium.org/2016/01/a-faster-more-stable-chrome-on-ios.html

@iest
Copy link
Contributor

iest commented Jan 31, 2016

Would ❤️ to know when this bugfix is released so I don't have to use a fork. Any ETA?

@nuc
Copy link

nuc commented Feb 4, 2016

History rc-3 is out, which removes the hack: remix-run/history#208 \o/

@oleg-andreyev
Copy link

oleg-andreyev commented Jul 29, 2016

Ref. to source in CriOS (about override pushState/replaceState):
https://chromium.googlesource.com/chromium/src/+/master/ios/web/web_state/js/resources/core.js#412
https://chromium.googlesource.com/chromium/src/+/master/ios/web/web_state/js/resources/core.js#427

So Chrome just added hooks before and after, so it seems as bug in UIWebView/WKWebView

@KaboomFox
Copy link

history doesn't seem to be working in 10.2. Any fix?

@lock lock bot locked as resolved and limited conversation to collaborators Jan 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants