Open duanyao opened 8 years ago
I don't think we need to add something to base
, it seems to me it should be possible to just fix this (i.e. specify the Firefox/Edge behavior).
For navigate I think the relevant step is
If this is not a reload-triggered navigation, resource is a request, resource's url equals browsingContext's active document's URL with exclude fragments flag set, and resource's url's fragment is non-null, then navigate to that fragment and abort these steps.
https://html.spec.whatwg.org/multipage/browsers.html#navigate
CSS/SVG needs to be handled in CSS and SVG specs, but I think there has been some work already to try to deal with this problem... cc @AmeliaBR @tabatkins
But what to do if there is a valid <base>
in a about:blank
doc, and we still want to resolve pure fragment urls against the doc? It seems about:blank#foo
works in Firefox and Chrome, but not in Edge.
Even if about:blank#foo
works, it is still very nasty to change every pure fragment urls.
Test case:
<!DOCTYPE html>
<iframe style="width:400px; height:400px"></iframe>
<script>
var frame = document.querySelector('iframe');
if (frame.contentDocument.readyState == 'complete') {
renderFrame();
} else frame.onload = renderFrame;
function renderFrame() {
if (!frame.contentDocument || frame.contentDocument.URL !== 'about:blank') {
return;
}
frame.contentDocument.head.innerHTML = '<base href="http://example.com" >';
var content = '';
for (var i = 0; i < 50; i++) {
content += '<p id="' + i + '">' + i + '</p>';
}
// go to http://example.com/#25 in all browsers
content += '<p><a href="#25">go to #25</a></p>';
// go to #25 in Chrome & Firefox, fail in Edge
content += '<p><a href="about:blank#25">go to about:blank#25</a></p>';
frame.contentDocument.body.innerHTML = content;
}
</script>
Just found that CSS has special behavior for fragment-only urls: always treat as same-document (rather than cross-document): https://drafts.csswg.org/css-values-3/#local-urls
Should HTML spec do the same thing?
I handled this in SVG 2 by requiring that, for SVG cross-references
For links, I reference the HTML rules (or W3C snapshot thereof), so I don't explicitly require the same comparison against document base URL before navigation. But if HTML makes it explicit, SVG will be expected to get the matching behavior.
In CSS it's a little more complicated, because they also wanted to enable same-document cross references (for properties like clip-path
) with CSS set in a .css file. So CSS Values and Units 4 adds a special rule that target-only URLs are always to be treated as same-document URLs, relative to whatever document contains the styled element.
PS, These are both recent spec changes; implementations have not been universally updated to match.
Thanks for the detailed explanation!
Maybe it's better to just fix the navigation rule of HTML: treat #foo
and document.baseURI + '#foo'
as same-document navigation. But I doubt whether this is web compatible.
URLs are only made absolute when needed
How does this work? Making a URL absolute is not something https://url.spec.whatwg.org/ supports. But assuming you mean parsing a URL string into a URL record, how can you only do that sometimes? And if do not do it at a deterministic point in time, you break blob URLs.
CSS, in particular, explicitly calls out hash-only urls (that is, values of the url()
function that start with a hash) as always being local. They still resolve to absolute URLs as normal, but they have an internal "local url" flag set, forcing them to serialize as hash-only, and making them always be interpreted as references to the current document only.
Now that this issue was closed, what was the resolution?
No change, basically. We're not going to add new features for this and changing the way fragment identifiers work seems extremely risky.
How about the different behaviors between Chrome and Firefox/Edge when navigating to #foo
or about:blank#foo
mentioned in this issue?
I'll reopen it for that since it does seem worth to add tests if we don't have any yet. I don't really understand how you get a new nested frame by following a link.
Which browser are you testing? Chrome 53 should load a nested iframe, not sure newer versions. Update: Chrome 60 still loads a nested iframe when click "go to the 25th" for the first time, but does nothing for following clicks.
It doesn't load a nested iframe here. It just navigates the iframe the link is in.
So you mean Chrome and Firefox have same behavior? Strange.
Can you try html this in Chrome? fragment-url-base-link-dynamic.htm.zip
The screenshot after clicking "go to the 25th" looks like
I think this is a duplicate of #421. I don't think I get different results from you, I'm just describing it differently.
I see. Is about:blank#25
case mentioned in https://github.com/whatwg/html/issues/1781#issuecomment-247039442 also covered by #421 ?
Yeah, it's basically that bug. But we can leave this open and close them together.
Currently pure fragment urls ("#foo") are resolved in the same way as normal relative urls, i.e. against base url. However sometimes we want to resolve pure fragment urls against current document regardless of the base url. For example:
<a>
) to a location inside document.clip-path
referencing a svgclipPath
inside the document.Currently, if the base url is not identical to the document url, those pure fragment urls are broken.
Someone suggested changing links to absolute ones via JS to workaround this issue. However this doesn't work for css
clip-path
, because the absolute url is pointing to a html document, not a svg. Additionally, if the document url is a special one (e.g.about:blank
), it is not even possible to figure out the absolute form of a pure fragment url.The following test case demonstrates the "fragment in
about:blank
" problem:What should a browser do when the link "go to the 25th" is clicked? Chrome 53 creates a nested iframe, while Firefox 51 and Edge 13 scroll to the the 25th line. I think Chrome's behavior is "technically correct" but is not what we want, while Firefox and Edge are the opposite.
So I suggest reusing
<base>
tag to specify base url of pure fragment urls, E.g.:Value "self" and "base" of
fragment-resolution
means pure fragment urls are resolved against the document itself, and the base url, respectively.