You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Revamp about:blank and about:srcdoc iframe/popup base URL inheritance #421
Update as of 2023-06-01 by @domenic: this issue has expanded to cover general base URL inheritance for about:blank iframes/popups, and about:srcdoc iframes. See #421 (comment) for the current proposal for how to update the spec and achieve interop.
In both cases, Blink uses "about:blank" as the base URL, but will actually look at the parent document's base URL while trying to resolve URLs in the iframe document.
@bzbarsky, can you describe what the model for this in Gecko is? Is it specific steps for iframe insertion, or does any of it also apply to frame elements, object elements, createDocument() or createHTMLDocument()?
Looking closer, I can't find any connection at all between HTML's various base URL concepts and DOM's base URL. The string "concept-document-base-url" appears nowhere in the generated HTML source, and the only link with exactly the text "base URL" is in script settings for browsing contexts but in fact refers to HTML's document base URL concept like all the rest.
@annevk, is this all entirely broken? How many concepts are the supposed to be, and how do they fit together?
The DOM definition doesn't seem quite right; I'd think we'd always want HTML's "document base URL" (except for resolving the base element's href attribute).
On the Blink bug, @bzbarsky said "My (and Firefox's) definition is the one that's in the spec, and the one that happens to make sense: .baseURI returns the thing that's used as the base URI."
Although I can't make sense of the specs, I agree that it would make a lot of sense if what document.baseURI returns is actually the base URL that's used to resolve URLs in that document. I also think it would be great if the base URL is an internal slot like in DOM, and not a computed value like in HTML. Then, script could do the exact equivalent by using new URL(relativeURL, document.baseURI). I'm not sure if fallback base URL makes that impossible.
If somebody has a detailed model in mind for this, it would be interesting to see in which ways Blink differs.
Maybe the question is whether this is the right way to spec it, since it doesn't actually match any implementations?
@bzbarsky, can you describe what the model for this in Gecko is?
Sure. Each document has a "baseURL" field, which may be null. Each document has a concept of "base URL", which is computed as follows: if the document is a srcdoc document and has a parent document (long story about why it might not have the latter, involving references to documents that outlive their browsing context), return the "base URL" of the parent document. Otherwise if the "baseURL" field is not null, return that. Otherwise return the "document's address" in HTML spec terms.
The "baseURL" field is set by several things; this may not be quite right because I'm trying to exclude codepaths that are only accessible to extensions, sorry:
Cloning a document via cloneNode will copy the "baseURL" field.
Adding/removing <base> elements or href attributes on them will set the field, possibly to null (because <base> elements assume they're the only ones who set the field, even though that's totally not the case).
Some document-creation codepaths take an explicit value to store in the field; I haven't looked at them very carefully. Mostly relevant for stuff created via DOMImplementation and I can look up the details if they really matter.
XMLHttpRequest responseXML documents will get the "baseURL" set to the final post-redirect URL, afaict.
Initial about:blank gets the base URL of the frameElement (in the .baseURI sense) of the window it's in as its "baseURL", as far as I can tell. But note that Gecko's initial about:blank is not quite the same thing as the spec's at the moment.
Documents loaded from various about: URIs, including non-initial about:blank (which is actually the spec's initial about:blank in some cases) get a "baseURL" in the following way: when initially converting the string to a Gecko URL object, we record the base URL the string was "resolved" relative to at the time (in quotes, because it's not a relative URL at all, of course; but we record the thing that would have been used as a base URL for resolving a relative URL if we'd had a relative URL). This base URL ends up in the "baseURL" field of the resulting document.
I fully expect that no one else does anything like item 6 in that list. It was a quick and easy hack to make about:blank generally more or less web-compatible a long time ago...
You're right that HTML's computed "document base URL" and "fallback base URL" explain why things are resolved correctly, but the DOM+HTML specs taken together don't explain why node.baseURI would ever be anything other than "about:blank".
So, we need to figure out at least:
Which base URL fields there should be and when they are updated. (Blink has 3)
What's used to resolve URLs.
What's used for node.baseURI.
There's a lot of small differences here, not sure how to proceed.
That's fair. My main design requirments here are (1) web compat, whatever that means and (2) having node.baseURI match what's actually used for relative URL resolution.
@bzbarsky you mostly describe base URL as a static field, but for srcdoc it's a computation? Or do we compute it once for srcdoc too and then update it as things change?
you mostly describe base URL as a static field, but for srcdoc it's a computation?
My comments above predated Gecko doing sane things for base URIs in srcdoc.
The current setup in Gecko is as follows:
Documents have a "document base URI" field which contains a URI or null.
This "document base URI" field is set in various places (creation of initial about:blank documents, some XSLT stuff, <base> elements being inserted/removed, something about DOMImplementation.createDocument, which apparently uses about:blank as the base URI?, various XHR/DOMParser bits, etc).
Getting the document base URI checks that field. If non-null, the value in it is returned. If null, for a srcdoc document the base URI of the parent is returned; for non-srcdoc the document URI is returned.
This has the somewhat unintuitive behavior that if you start with an initial about:blank, insert a <base href>, and then remove it, you end up with a different base URI than you started with. In practice that hasn't been a problem.
(Aside: the idea is that for all Document objects the default base URL would be "about:blank", since we didn't want baseURI to return a non-URL value.)
Why can't we set it when creating a srcdoc document too?
We can. The question is whether the srcdoc should dynamically track the base URI of the parent or not (i.e. snapshot it at creation time) and how <base> removal in srcdoc should behave. The current setup in Gecko was basically done to align closer with the current srcdoc spec.
Okay. I tend to think we should just snapshot it at creation time (and then only change it for <base> changes inside the srcdoc document), but I guess at this point we might be looking at compat fallout :/
As general background when talking about inheritance discussions, there are potentially two parties involved: creator (= embedder for iframes), and navigation initiator. These two are the same for the initial about:blank, but are not the same in general, including for non-initial about:blank or for about:srcdoc.
I believe the team's proposal is:
about:srcdoc frames inherit base URL from their embedder at document creation time, and it is snapshotted then.
about:blank frames+popups inherit base URL from their navigation initiator at document creation time, and it is snapshotted then.
Related issues are #2883 and #3989. (Plus #8105, which is a proposal for a change to limit how much of the base URL is inherited; but IMO we should only explore that after first getting interop.)
Implications of this proposal:
Disconnected iframes keep their base URL. The current spec "crashes" for srcdoc iframes in such cases.
Base URLs do not update in response to parent or creator base URLs changing. The current spec does such dynamic updates for both about:srcdoc and about:blank.
We will align base URL inheritance with origin inheritance, for cases where people navigate to a non-initial about:blank. The current spec has such about:blank windows always inherit base URL from their creator and origin from the navigation initiator; we will align both on navigation initiator.
One addition to the plan: we believe we'll need to store the base URL in the session history entry for such documents, just like we do for the origin currently. This helps in cases like: https://example.com/ opens an about:blank popup, which has a base URL; that popup navigates to https://other.example/; the opener window closes; then the popup traverses back (no bfcache). In such cases we should keep the base URL of https://example.com/ for the popup even when it's back on about:blank.
There are a few other possible ways to get the desired behavior here, but we think using the session history entry is nicest because it's symmetrical with what we're already doing with origin.
changed the title [-]Iframes should inherit the base URL of the parent document in some cases[/-][+]Revamp about:blank and about:srcdoc iframe/popup base URL inheritance[/+]on Jun 1, 2023
Activity
foolip commentedon Dec 18, 2015
Looking closer, I can't find any connection at all between HTML's various base URL concepts and DOM's base URL. The string "concept-document-base-url" appears nowhere in the generated HTML source, and the only link with exactly the text "base URL" is in script settings for browsing contexts but in fact refers to HTML's document base URL concept like all the rest.
@annevk, is this all entirely broken? How many concepts are the supposed to be, and how do they fit together?
Ms2ger commentedon Dec 18, 2015
The DOM definition doesn't seem quite right; I'd think we'd always want HTML's "document base URL" (except for resolving the
baseelement'shrefattribute).annevk commentedon Dec 18, 2015
My idea was that the DOM defines a base URL concept for documents and HTML takes care of setting it as appropriate. None of this is quite done.
foolip commentedon Dec 18, 2015
On the Blink bug, @bzbarsky said "My (and Firefox's) definition is the one that's in the spec, and the one that happens to make sense: .baseURI returns the thing that's used as the base URI."
Although I can't make sense of the specs, I agree that it would make a lot of sense if what
document.baseURIreturns is actually the base URL that's used to resolve URLs in that document. I also think it would be great if the base URL is an internal slot like in DOM, and not a computed value like in HTML. Then, script could do the exact equivalent by usingnew URL(relativeURL, document.baseURI). I'm not sure if fallback base URL makes that impossible.If somebody has a detailed model in mind for this, it would be interesting to see in which ways Blink differs.
bzbarsky commentedon Jan 7, 2016
@foolip So on the HTML spec end, I'm not sure what this issue is even about. The "should inherit" behavior is already covered by the "fallback base URL" as defined at https://html.spec.whatwg.org/#fallback-base-url and the corresponding use in https://html.spec.whatwg.org/#document-base-url
Maybe the question is whether this is the right way to spec it, since it doesn't actually match any implementations?
Sure. Each document has a "baseURL" field, which may be null. Each document has a concept of "base URL", which is computed as follows: if the document is a srcdoc document and has a parent document (long story about why it might not have the latter, involving references to documents that outlive their browsing context), return the "base URL" of the parent document. Otherwise if the "baseURL" field is not null, return that. Otherwise return the "document's address" in HTML spec terms.
The "baseURL" field is set by several things; this may not be quite right because I'm trying to exclude codepaths that are only accessible to extensions, sorry:
cloneNodewill copy the "baseURL" field.<base>elements orhrefattributes on them will set the field, possibly to null (because<base>elements assume they're the only ones who set the field, even though that's totally not the case).DOMImplementationand I can look up the details if they really matter.XMLHttpRequestresponseXML documents will get the "baseURL" set to the final post-redirect URL, afaict.about:blankgets the base URL of theframeElement(in the.baseURIsense) of the window it's in as its "baseURL", as far as I can tell. But note that Gecko's initialabout:blankis not quite the same thing as the spec's at the moment.about:URIs, including non-initialabout:blank(which is actually the spec's initial about:blank in some cases) get a "baseURL" in the following way: when initially converting the string to a Gecko URL object, we record the base URL the string was "resolved" relative to at the time (in quotes, because it's not a relative URL at all, of course; but we record the thing that would have been used as a base URL for resolving a relative URL if we'd had a relative URL). This base URL ends up in the "baseURL" field of the resulting document.I fully expect that no one else does anything like item 6 in that list. It was a quick and easy hack to make about:blank generally more or less web-compatible a long time ago...
foolip commentedon Jan 11, 2016
When filing this issue, I was looking for some kind of interaction with DOM's "base URL", and I expected the "base URL" field to be updated somewhere in https://html.spec.whatwg.org/#creating-a-new-browsing-context, which does not happen.
You're right that HTML's computed "document base URL" and "fallback base URL" explain why things are resolved correctly, but the DOM+HTML specs taken together don't explain why
node.baseURIwould ever be anything other than "about:blank".So, we need to figure out at least:
node.baseURI.There's a lot of small differences here, not sure how to proceed.
bzbarsky commentedon Jan 11, 2016
That's fair. My main design requirments here are (1) web compat, whatever that means and (2) having
node.baseURImatch what's actually used for relative URL resolution.foolip commentedon Jan 11, 2016
Yeah, I agree with those goals.
It sounds like tests for a number of different documents are needed.
<iframe>with no attributes (about:blank),<iframe src>and<iframe srcdoc><frame>document.open()document.implementation.create*Document()XMLHttpRequestFor each of those, check
node.baseURIand the actual base URL used to resolve:<base>element<base>elementUse HTML's 'document base URL' concept.
Use HTML's "document base URL" concept
annevk commentedon May 9, 2017
@bzbarsky you mostly describe base URL as a static field, but for srcdoc it's a computation? Or do we compute it once for srcdoc too and then update it as things change?
annevk commentedon May 9, 2017
@foolip tests for XMLHttpRequest: web-platform-tests/wpt#5863.
bzbarsky commentedon May 9, 2017
My comments above predated Gecko doing sane things for base URIs in srcdoc.
The current setup in Gecko is as follows:
<base>elements being inserted/removed, something about DOMImplementation.createDocument, which apparently uses about:blank as the base URI?, various XHR/DOMParser bits, etc).This has the somewhat unintuitive behavior that if you start with an initial about:blank, insert a
<base href>, and then remove it, you end up with a different base URI than you started with. In practice that hasn't been a problem.1 remaining item
annevk commentedon May 9, 2017
(Aside: the idea is that for all
Documentobjects the default base URL would be "about:blank", since we didn't wantbaseURIto return a non-URL value.)bzbarsky commentedon May 9, 2017
We can. The question is whether the srcdoc should dynamically track the base URI of the parent or not (i.e. snapshot it at creation time) and how
<base>removal in srcdoc should behave. The current setup in Gecko was basically done to align closer with the current srcdoc spec.annevk commentedon May 9, 2017
Okay. I tend to think we should just snapshot it at creation time (and then only change it for
<base>changes inside the srcdoc document), but I guess at this point we might be looking at compat fallout :/hiroshige-g commentedon Apr 21, 2020
Drafted WPT just for
<iframe srcdoc>: web-platform-tests/wpt#23130Chromium: Takes snapshot of parent's base URL around the time of
<iframe srcdoc>.Firefox: Reflects parent's updates dynamically.
(The opposite direction from #5474, where Chromium reflects parent's referrer policy updates while Firefox takes snapshot)
domenic commentedon Sep 28, 2022
Some parts of the Chrome team (@csreis @wjmaclean) have started investigating this area in https://bugs.chromium.org/p/chromium/issues/detail?id=1356658 . We'd love to get interop on base URL inheritance in general, and I've volunteered to help with the spec discussions.
As general background when talking about inheritance discussions, there are potentially two parties involved: creator (= embedder for iframes), and navigation initiator. These two are the same for the initial about:blank, but are not the same in general, including for non-initial about:blank or for about:srcdoc.
I believe the team's proposal is:
about:srcdoc frames inherit base URL from their embedder at document creation time, and it is snapshotted then.
about:blank frames+popups inherit base URL from their navigation initiator at document creation time, and it is snapshotted then.
Related issues are #2883 and #3989. (Plus #8105, which is a proposal for a change to limit how much of the base URL is inherited; but IMO we should only explore that after first getting interop.)
Implications of this proposal:
Disconnected iframes keep their base URL. The current spec "crashes" for srcdoc iframes in such cases.
Base URLs do not update in response to parent or creator base URLs changing. The current spec does such dynamic updates for both about:srcdoc and about:blank.
We will inherit the base URL for about:srcdoc iframes that are not srcdoc documents, as discussed in Fallback base URL computation for a document with about:srcdoc but not an iframe srcdoc document #3989. Separately we can continue discussion there about perhaps preventing such documents from ever being created in the first place...
We will align base URL inheritance with origin inheritance, for cases where people navigate to a non-initial about:blank. The current spec has such about:blank windows always inherit base URL from their creator and origin from the navigation initiator; we will align both on navigation initiator.
annevk commentedon Sep 28, 2022
This generally sounds good to me. Thank you for working on it! cc @cdumez
domenic commentedon Oct 4, 2022
One addition to the plan: we believe we'll need to store the base URL in the session history entry for such documents, just like we do for the origin currently. This helps in cases like:
https://example.com/opens anabout:blankpopup, which has a base URL; that popup navigates tohttps://other.example/; the opener window closes; then the popup traverses back (no bfcache). In such cases we should keep the base URL ofhttps://example.com/for the popup even when it's back onabout:blank.There are a few other possible ways to get the desired behavior here, but we think using the session history entry is nicest because it's symmetrical with what we're already doing with origin.
Navigation and session history rewrite
[-]Iframes should inherit the base URL of the parent document in some cases[/-][+]Revamp about:blank and about:srcdoc iframe/popup base URL inheritance[/+]Snapshot fallback base URL for about:-schemed Documents