Closed guybedford closed 3 years ago
It might make sense to only allow scoping subspaces for special schemes.
In the current draft spec, the answsers are all Yes, but I think just for generality; There are no specific use cases, while there are no strong reasons to forbid, so the current draft spec is written in an "allow everything" style. If there are concerns, I think we can/should add limitations.
(In general, I'm not confident about how to handle cases that look a bit scary like this; If attackers can inject malicious import maps or malicious specifiers, I expect the attackers should be able to inject malicious scripts directly (this depends on import map+CSP design though), so import maps don't increase attack surfaces. On the other hand, conservatively forbidding scary cases (with no valid use cases) might prevent unexpected security issues. Anyway I welcome inputs)
@bmeck's point about scoping being weird for non-special schemes seems most important here. A scope of "data:application/"
means something very different than a scope of "https://application/
.
Otherwise I tend to lean toward letting people remap specifiers even if those specifiers look like data: URLs, or using import maps to create aliases for data: URLs instead of importing them directly.
After #176, the latter case ("x/": "data:application/javascript,//"
) always fails, because now we handle trailing-slash matching by relative URL parsing (and using data: URLs as base URLs fails).
The former case still works.
Can you still map identifiers to data URLs?
I find myself using things like AMD because I can inline many modules in the page. Import maps + data URLs will provide the same functionality.
@jakearchibald Could you please elaborate? Are you saying you'd be able to have AMD-like bundles (a single JS file) using import maps + data URLs? That's very interesting, but I fail to see how you would achieve that :-/
When we built https://proxx.app/, we wanted to improve performance by inlining the JS for the first interaction. The first interaction was a set of modules, some of which weren't exclusive to the first interaction (eg helper functions).
When the "later interaction" modules loaded, we wanted them to be able to import modules from the initial set that were inlined into the page.
Because AMD allows many modules to be defined in a single script, this was pretty easy to achieve.
I'm wondering if import maps can bring the same functionality to standard modules:
<script type="importmap">
{
"./utils.mjs": "data:text/javascript;charset=utf-8,export%20const%20log%20%3D%20msg%20%3D%3E%20console.log%28msg%29"
}
</script>
<script type="module">
import { log } from './utils.mjs';
log('Hi!');
</script>
In the above, import maps have been used to inline ./utils.mjs
.
Thanks for the explanation. If data URLs are supported, Import maps allow inlining scripts in the import map itself. That's great (minus cache) for the first load, however, it does not solve the problem for bundled content that you would wish to load lazily... Unless, of course, multiple import maps were supported (they'd been removed for MVP) and allowed to be added after loading had started...
Can you still map identifiers to data URLs?
Yes.
multiple import maps were ... allowed to be added after loading had started
Currently I expect this is unlikely to happen (I haven't figure out how to achieve this in the spec/impl).
I'm wondering if import maps can bring the same functionality to standard modules:
It will break any relative URLs inside the data url, since they'll become relative to the data url.
Brought up by @jkrems on Twitter - do we permit these mappings? And if so, does that mean that a data: URI with a trailing slash is permitted as a folder mapping?
eg:
would the above map any content after the data URI above to the local URL? And conversely:
would the above map
x/\nconsole.log('hi')
into its executable data URI?