Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$location.url(url).replace() with HTML5Mode on causes page reload #16418

Closed
poshest opened this issue Jan 22, 2018 · 9 comments
Closed

$location.url(url).replace() with HTML5Mode on causes page reload #16418

poshest opened this issue Jan 22, 2018 · 9 comments

Comments

@poshest
Copy link
Contributor

poshest commented Jan 22, 2018

This is a bug, all browsers. I believe it was introduced as part of these changes.

I have a page with elements. Clicking on an element should add the elementID as a hash thus

http://mysite.com/basepath#elementID

... but without any history changes. Like how Google docs headings create an anchor tag so you can share a deeplink with friends. So I'm adding the elementID to the current url (or replacing an existing hash with a new one) and then calling $location.url(url).replace().

The trouble is on every element click, the page reloads. The trouble is in this block

 var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
 ...
  // Don't use history API if only the hash changed
  // due to a bug in IE10/IE11 which leads
  // to not firing a `hashchange` nor `popstate` event
  // in some cases (see #9143).
  if ($sniffer.history && (!sameBase || !sameState)) {
    history[replace ? 'replaceState' : 'pushState'](state, '', url);
    cacheState();
  } else {
 ...
    if (replace) {
      location.replace(url);
    }
 ...
 }

I really want a history.replaceState, but instead, because of the "sameBase" logic, I'm heading into the IE bug fallback territory (even on Chrome, Firefox, etc). Calling location.replace() at this point reloads the page, which is not what I want.

I spent hours trying to get a Plunkr working for this. http://plnkr.co/edit/ugSUq7NdQonCS94JlbIj It adequately describes my use case, but I cannot re-create the reload issue. I believe it's because the Plunkr is run in an iframe for which location.replace() doesn't actually do a reload? :P

HEADS UP! The Plunkr will not work out of the box. That <base> tag which is required by HTML5Mode means I have to (at least I didn't find another way) hard code the URL from which Plunkr serves the sandboxed code. AND THAT URL CHANGES FOR EVERY SESSION! :/ :/ :/ So to get the Plunkr working, you need to

  1. open dev tools
  2. hit Stop and Run on the Plunkr
  3. find the request which looks like http://run.plnkr.co/2DiB4CfmPFdmyPMp/ and put the 2DiB4CfmPFdmyPMp into the <base> tag, eg <base href="//run.plnkr.co/2DiB4CfmPFdmyPMp/">

Then you can click anchors and at least see that the code enters to that location.replace(url); line.

If anyone can make it work out of the box, I'd be grateful for instructions.

Anyhoo, how is it possible to use $location to achieve a hash add, change or removal without reloading the page?

@Narretz
Copy link
Contributor

Narretz commented Jan 24, 2018

This sounds vaguely familiar. Have you searched for similar issues?

@poshest
Copy link
Contributor Author

poshest commented Jan 24, 2018 via email

@poshest
Copy link
Contributor Author

poshest commented Jan 24, 2018 via email

@Narretz
Copy link
Contributor

Narretz commented Jan 24, 2018

Ok. location is notoriously tricky, so I was just double checking before we do duplicate work.
In your specific example, have you tried with $location.hash() ?
This works fine for me: http://plnkr.co/edit/yFD6CUQhs9P2jXPEW3j1?p=preview

@poshest
Copy link
Contributor Author

poshest commented Jan 24, 2018 via email

@Narretz
Copy link
Contributor

Narretz commented Jan 25, 2018

Well, color me confused. I double checked your original example and I don't get the reload behavior there either - in Firefox and in Chrome.

@poshest
Copy link
Contributor Author

poshest commented Jan 25, 2018 via email

@gkalpak
Copy link
Member

gkalpak commented Jan 25, 2018

@poshest, in order to make plnkr work without having to hard-code the base href, you can use the following:

<head>
  <script>document.write('<base href="' + document.location + '" />');</script>
  ...

That said, I cannot replicate the reloading neither in the iframe, nor outside (plnkr has a button on the top-right corner of the preview pane that allows you to open the app without the iframe). Not even on a regular page.

When only the hash changes, location.replace() does not reload the page for me (on Chrome at least).

I'm afraid there is not much we can do without a working reproduction, so I am going to close this for now. Happy to re-open and investigate more once you can provide a working demo.

@gkalpak gkalpak closed this as completed Jan 25, 2018
@poshest
Copy link
Contributor Author

poshest commented Jan 25, 2018 via email

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

3 participants