Skip to content
This repository has been archived by the owner on Dec 31, 2022. It is now read-only.

Pages created in iframe srcdoc attribute #93

Open
angloc opened this issue Dec 14, 2013 · 4 comments
Open

Pages created in iframe srcdoc attribute #93

angloc opened this issue Dec 14, 2013 · 4 comments
Labels

Comments

@angloc
Copy link

angloc commented Dec 14, 2013

It is useful sometimes to create the HTML text for an iframe in Javascript and send it to the iframe in the srcdoc attribute. This is most frequently used for self-contained HTML but the document can legitimately access remote resources, and for this purpose HTML provides the element so that relative links in the document are resolved with respect to some external absolute path, rather than with respect to the srcdoc text which would be meaningless.
lab.js requires to know the absolute path to the root of its client document, and captures it in the 'rootpath' variable.
Unfortunately lab.js is not sensitive to this particular use case and finds the rootpath simply by looking at location.href, which doesn't return anything useful for a srcdoc, and in fact causes a Javascript exception.
I haven't worked out a robust fix for this but substituting:
root_page = document.getElementsByTagName("base")[0].href
for
root_page = /^[^?#]*//.exec(location.href)[0]
in line 19 of V2.0.3 source succeeds when the other fails, and vice versa.
Obviously the HTML text you create for your srcdoc has to contain an appropriate <base> element in its <head>,

@getify
Copy link
Owner

getify commented Dec 14, 2013

Never heard of this use-case before now. But yeah, we definitely don't want to rely on the <base> tag. So I don't know what an automatic solution would be.

Can you try manually setting, in the HTML of the srcdoc, location.href = "" or something like that before you include the LABjs code, to see if it prevents the JS error that LABjs encounters? Then, if you set the BasePath config variable to some absolute, it should substitute for <base> and it should work for you.

@angloc
Copy link
Author

angloc commented Dec 15, 2013

Thanks for such a rapid response Kyle.

I’m afraid setting location.href doesn’t work because it effectively refreshes the page with the contents of whatever is the new value of location.href. Setting it to blank is probably not defined behaviour in the DOM spec – and in any case causes LAB initialisation to fail because it doesn’t match the RE executed on line 18.

I hadn’t RTFM properly so I didn’t see the BasePath variable. I expect that will work once LAB is loaded, but LAB won’t load unless the RE in line 18 returns a match.

I fear this can’t be made to work with the present sources. A fix might be to attempt to match the RE and if that fails then to look at any element present before giving up. The code would need quite significant change I think because the chain of variable definitions needs to be broken. Depends how important you feel this issue is.

@getify
Copy link
Owner

getify commented Dec 16, 2013

For security reasons, there doesn't appear to be any way to hijack/override location or location.href. So that monkey patching won't work.

I'm yet to be convinced that there is a good work-around for URL handling when you're in an iframe that's essentially URL-less. I'm not convinced of what a good clean fall-back is, but I know that <base> is not what I'd want.

One option is if there's no location, then LABjs doesn't try to do any URL resolving/canonicalization. This sounds good on the surface, until you realize that LABjs does this only so you get the kind of behavior you expect around "duplicates" handling, especially when referencing the same script with different types of relative URLs. Users expect the tool to "know" these are the same, and the only way to do that is to resolve them all against a base URL, the window location being the appropriate one.

Not doing canonicalization of the URLs will likely lead to strange gotchas around duplicates, so it is similarly a bad route to head down, IMO.

Another option is to fake some base URL like "http://some.tld" in the case of a missing one, so that all the logic works correctly. But then there's issues where a protocol-relative URL like "//someother.tld/foo/bar" URL would expect the correct http vs. https switching, which we really can't do. So this is a bad route.

Another option is to have LABjs try to look up to a parent frame if the current page has no URL, under the assumption that some frame in the heirarchy in the browser must have a URL. But I'm not sure if security things like CSP would prevent this sort of thing from inside a srcdoc iframe. That would take a lot of research and proving. But it's the only option I see so far which is remotely plausible.


Then, we have to step back and ask if benefits of this fix, niche as it is, justifies the "pain" of the fix. I'm not really convinced it does. This is the first time in 4-1/2 years someone's asked for it. The stability of LABjs is every bit as important a feature as any other, at this point.

So I think we could research if there's a fix, but then you'd probably just need to run your own patched version of LABjs with such a fix. If we got a bunch of people asking for this, and if we had other bugs or features that were waiting and could be collected into a compelling enough of a set for a justifiable release, we could consider it some day.

@angloc
Copy link
Author

angloc commented Dec 17, 2013

I hear what you say and I understand this is an obscure situation. I have a patch that works well for me when I supply a base, so that’s fine. My situation is I generate some information on the client side I want to incorporate in the page coming into the iframe from (my tame) server. This is too bulky to incorporate in the URL for the iframe, and waiting until the iframe DOM is complete to insert it involves changing the server side code and some complex synchronisation issues at the client end. So what I do is generate the page that the server would have generated if it only had the information that I have in the client, and provide that as the srcdoc for the iframe. The only problem is this page needs to be re-based to the server root address so all the resources of the page load correctly. The browsers seem to cope fine with this but LAB.js fails because it needs the location.href.

Writing this it occurs to me that maybe I could insert as the srcdoc some Javascript code that would make a POST request to the server incorporating all the data I want, and using the resulting HTML text to replace its own document. This should then behave in the ordinary manner without needing a base and an unpatched LAB.js should work fine.

Anyway it’s my problem and I really appreciate the time you’ve taken to consider and respond. I submitted the issue in case it was of interest elsewhere and so that hopefully if someone else is affected they will find this dialogue and save some time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants