Open Bug 1297077 Opened 8 years ago Updated 2 years ago

window.history.pushState/replaceState doesn't resolve empty URLs against base tag href

Categories

(Core :: DOM: Navigation, defect, P3)

48 Branch
defect

Tracking

()

People

(Reporter: henryptung, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Build ID: 20160817112116

Steps to reproduce:

1. Set up a page with a <base> tag pointing somewhere other than the page itself
2. Call `window.history.pushState(null, null, "")` inside the page

(See demo plnkr: http://plnkr.co/edit/TXt4upObOBtCY8G1Vae2)

Notes:
- replaceState behaves the same way as pushState does
- Non-empty relative URLs (e.g. ".") and path-absolute URLs (e.g. "/") do work, but are not guaranteed to be the same as the <base> tag href (e.g. for a non-directory base href, "." points at the parent directory).


Actual results:

The location bar stayed at the page's URL.


Expected results:

Expected the location bar to change to the URL of the base tag.
Summary: window.history.pushState/replaceState treats empty URLs incorrectly → window.history.pushState/replaceState doesn't resolve empty URLs against base tag href
After looking into it some more, https://github.com/mozilla/gecko-dev/blob/021c9d40ae886b3ac6e9a7dcfd8cb7fdf9910ae0/docshell/base/nsDocShell.cpp#L11805 seems like the aberrant line. If it's trying to optimize away the base URI resolution process, it should probably use `document->GetDocBaseURI()` instead.

Note: If I understand correctly, using `document->getDocBaseURI()` is still technically wrong since the resolution process should never adopt the base URI's fragment, even when no fragment is specified in the relative URL; see https://tools.ietf.org/html/rfc3986#section-5.2.2. Not sure if the optimization for empty string is actually worth the extra complexity here...
This is not an Activity Stream issue. Activity Stream is a Test Pilot experiment.

I'm moving your issue to a possible related component.
Component: Activity Streams: General → Networking: HTTP
Product: Firefox → Core
Component: Networking: HTTP → Document Navigation
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P3
Step 7 of the spec [1] reads "If the third argument is null, then let new URL be the URL of the current entry." so I think it should be expected, shouldn't it?

[1] https://html.spec.whatwg.org/multipage/browsers.html#dom-history-pushstate
(In reply to Samael Wang [:freesamael][:sawang] from comment #3)
> Step 7 of the spec [1] reads "If the third argument is null, then let new
> URL be the URL of the current entry." so I think it should be expected,
> shouldn't it?
> 
> [1]
> https://html.spec.whatwg.org/multipage/browsers.html#dom-history-pushstate

Maybe Anne could confirm?
Flags: needinfo?(annevk)
Ah I see this one's not null but empty string.
I guess we just need to change the condition to `if (aURL.IsVoid())` instead:
http://searchfox.org/mozilla-central/rev/39e4b25a076c59d2e7820297d62319f167871449/docshell/base/nsDocShell.cpp#12021
Flags: needinfo?(annevk)
(Just make sure to test other browsers and add to web-platform-tests.)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.