Open Bug 1436489 Opened 8 years ago Updated 6 months ago

Consider not returning the real session history length from history.length

Categories

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

enhancement

Tracking

()

People

(Reporter: nika, Unassigned)

References

(Blocks 1 open bug)

Details

Currently the `history.length` API exposes the number of history entries which are present in the full session history. However, there is no way to determine what the current offset into this set of history entries is, meaning that the value is almost completely useless. bz and I tried to find consumers of this API, and the only one we found was for a page in a chrome extension which wanted to immediately go back when it was visited, which did the following: if (window.history.length > 1) { history.back(); } else { window.close(); } Technically, even this code was wrong as if the current document is being loaded from somewhere in history, we may not be able to go back, but the history length will still be greater than 1. I think that, because of the uselessness of this particular API, it may be possible for us to not expose this information to websites. There are a couple of options which immediately come to mind: return 1; - This might make websites think they can never go back, which may break things return 2; - This means that websites can't know if they can go forward or back, so ideally it shouldn't break anything. return 2 + # of times pushState is called in current page - This makes the value of history.length appear consistent from the point of view of a webpage which is trying to manipulate it, which may be valuable. (N.B. if you go back and then pushState again, the logic would have to account for that too, but it shouldn't be too difficult I think) I'm interested in discussing the implications of this change, and whether or not it would be web-compatible.
> However, there is no way to determine what the current offset into this set of history entries is, meaning that the value is almost completely useless. We attempted to solve this in https://github.com/whatwg/html/issues/2710 / https://github.com/whatwg/html/pull/2944 and even added history.index to the spec. However after that was merged Gecko mentioned that it would be impossible for them to implement it: https://github.com/whatwg/html/issues/2985 . Since then it seems Chrome and WebKit have not yet shipped history.index either. I'm not sure where that leaves us, except to say that making history even less useful seems to go against web developer-expressed desires.
Part of the problem from our point of view, ignoring implementation issues, is that history.length/index is a cross-site information and privacy leak. We've been trying to find out what use cases people have for these. Information on that would be really helpful.
I initially proposed `history.index` and indeed there were issues on Gecko, especially due to iframes being able to push history state and especially when these iframes are then removed. I believe Gecko currently clears out iframes' history entries. No matter what we do further, we need to keep this case in mind. The question: what does "# of times pushState is called in current page" mean? Is it number of times pushState called in this instance of the page since it was loaded? What would happen here if the page was refreshed? In the surface, "return 2 + # of times pushState is called in current page" sounds somewhat better. I think the only way to use `history.length` is in a relative way and the problem is figuring out what that "relative" starting point is and how it survives refreshes. I tried to summarize some thinking about web history in https://medium.com/@dvoytenko/new-web-history-api-91a1a21ff7b8
Nika, could you please set a priority for this so it's removed from triaging? (Note that since the previous comments history.index has been removed from the HTML Standard.)
Flags: needinfo?(nika)
Gonna mark it as P3 because I don't think we'll be doing this soon.
Flags: needinfo?(nika)
Priority: -- → P3
Another option here is to encode some website's (admittedly odd) behaviour around reading `history.length`. Specifically, we could have the value look something like: Let 'localHistory' be the range of consecutive history entries associated with the toplevel global's active document. Let 'localCount' be the number of entries in 'localHistory'. Let 'historical' be '1' if no entry exists before the first entry in 'localHistory' (i.e. the index of 'localHistory[0]' is '0'), else '0' Let 'length' be 'localCount + historical'. ---- This has the following properties: 1. Within a single toplevel document, changes to history are consistent, meaning that the effects should generally not be web-observable. 2. Assuming no intra-document history entries have been added, 'history.length' is '1' if you cannot go back, and '2' otherwise. (2) lines up with the only uses of history.length which I've seen, which aim to detect whether they were opened as a fresh tab (i.e. with 'window.open(...)' or 'target="_blank"'), or navigated within in an existing tab. This is usually used to decide whether to close the current tab.
Blocks: 1315203

We discussed this during the work week and considered testing this out. Olli, do you have more thoughts on this and whether now is a good time to try it?

Flags: needinfo?(bugs)

I don't see how this would be really blocking any Fission work, so not sure whether we want to do this now.

Flags: needinfo?(bugs)

And counting pushStates isn't enough, since we'd need to count also fragment navigations. And number 1 and 2 might not be enough.
2 could easily break sites if one has a landing page, then couple of pages after that.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.