Разница между конструктором URL () и якорным элементом заключается в том, что конструктор URL () не является ни узлом, ниприкрепленный к определенному Document объекту, и поэтому не имеет baseURI , который он может зацепить.
Так что вам нужно, чтобы конструктор URL () вел себя так же, как и якорный элемент , чтобы передать baseURI в качестве второго аргумента конструктора .
Это означает, что в документе new URL(uri, document.baseURI)
будет возвращать те же свойства URL, что и Object.assign(document.createElement('a'), {href: uri})
, при условии, что URI произведен является допустимым.
Теперь, в Worker у нас все еще нет доступа к Node baseURI , и это довольнонепонятно, что вы хотите зацепить.
В большинстве случаев вы можете просто использовать self.location.href
в качестве базового URI, и это на самом деле может быть тем, что вам нужно, если вы собираетесь получать ресурсы того же источника, но если вы действительно инициализируете свой Worker изblobURL, возможно, вам придется пропустить его из основной области, так же, как я это делал в сверхзащищенном фрейме StackSnippet®.
// init worker from a blobURI...
const worker_url = getWorkerURL(worker_script);
const worker = new Worker(worker_url);
worker.onmessage = e => console.log(e.data);
worker.postMessage({
// we pass the base URL
base: 'https://samedomain.com/foo.html',
uris: [
'https://notsamedomain.com/foo.jpg',
'../relative/image.png',
'/absolute/thing.jpg',
'//other/absolute/thing.jpg',
'https://samedomain.com/bar.gif'
]
});
//__MISC__________
// gets our Worker's blobURL based on a Blob made
// from a <script> element textContent
function getWorkerURL(el) {
const content = el.textContent;
const blob = new Blob([content], {type: 'application/javascript'});
return URL.createObjectURL(blob);
}
<script id="worker_script" type="worker_script">
onmessage = e => {
const d = e.data;
// if we weren't in a null origined iframe's blobURI we could do
//const self_url = new URL(location.href)
// but here we pass the fake base domain
const self_url = new URL(d.base);
const sameorigins = d.uris.filter( uri => {
try { // wrap in a try-catch, invalids throw
const url = new URL(uri, self_url);
return url.origin === self_url.origin;
} catch(e) { return false; }
})
postMessage(sameorigins);
};
</script>