Problem in brief
Changes to the "history entry" URL using history.replaceState() are not correctly reflected to location.hash and in certain conditions also not to location.href.
Reproducing
Below code shows behaviors of HtmlUnit and expected (tested in Chrome).
<!DOCTYPE html>
<html>
<head>
<script>
// Comments below assume 'location.href' is "https://www.example.com/some/path"
history.replaceState(null, '', location.origin + '/abc?def=1#foo');
// Expected:
// --> "href=https://www.example.com/abc?def=1#foo, hash=#foo"
// HtmlUnit without "Cache-Control: no-store":
// --> "href="https://www.example.co/abc?def=1#foo, hash=" -- bad 'hash'
// HtmlUnit with "Cache-Control: no-store":
// --> "href="https://www.example.com/some/path, hash=" -- bad 'href' and 'hash'
console.log("href=" + location.href + ", hash=" + location.hash);
</script>
</head>
<body>
</body>
</html>
Some thoughts
history.replaceState() updates the original WebRequest.url_
location.hash is cached in Location.hash_ which is not updated by history.replaceState()
- We were looking into how this could be fixed and there's some awkwardness because of the lacks a "history entry" URL concept for
history.replaceState() that's separate from the transport layer WebRequest.url_. Possibly adding this new concept to Page or History.HistoryEntry or Location is required.
- We also noticed there's some differences when encoding is required for the URL set through
history.replaceState():
- e.g.
history.replaceState(null, '', location.href + '?foo=Ż') produces "...?foo=%C5%BB" when location.href is viewed through Chrome but "...?foo=Ż" for HtmlUnit.
Problem in brief
Changes to the "history entry" URL using
history.replaceState()are not correctly reflected tolocation.hashand in certain conditions also not tolocation.href.Reproducing
Below code shows behaviors of HtmlUnit and expected (tested in Chrome).
Some thoughts
history.replaceState()updates the originalWebRequest.url_location.hashis cached inLocation.hash_which is not updated byhistory.replaceState()history.replaceState()that's separate from the transport layerWebRequest.url_. Possibly adding this new concept toPageorHistory.HistoryEntryorLocationis required.history.replaceState():history.replaceState(null, '', location.href + '?foo=Ż')produces"...?foo=%C5%BB"whenlocation.hrefis viewed through Chrome but"...?foo=Ż"for HtmlUnit.