这里有一个类似的问题
javascript How to check if a URL is same origin as current page?
不幸的是,它没有指定答案必须同时在页面和工作程序中起作用,因此所有答案都不能在工作程序中起作用。
特别是我正在尝试使用fetch API以尽可能自动的方式来获取图像。提取图像后,我想将模式设置为cors
,但前提是URL的来源不同。我需要知道如何在页面上下文和辅助上下文中做到这一点。
伪代码
function loadImageBitmap(url) {
const options = {};
if (urlIsNotSameOrigin(url)) {
options.mode = 'cors';
}
return fetch(url, options)
.then((response) => {
if (!response.ok) {
throw response;
}
return response.blob();
}).then((blob) => {
return global.createImageBitmap(blob);
});
}
function urlIsNotSameOrigin(url) {
// what do I put here?
}
// examples
async function main() {
const bitmaps = Promise.all([
'https://notsamedomain.com/foo.jpg',
'../relative/image.png',
'/absolute/thing.jpg',
'//other/absolute/thing.jpg',
'https://samedomain.com/bar.gif',
].map(loadImageBitmap));
}
我看到的大多数解决方案都是制作一个锚点<a>
元素,分配src
属性,然后读取它。但是工作人员中不存在锚。 URL
对象似乎无法像锚一样处理相对资源。
答案 0 :(得分:2)
URL()构造函数和锚点 元素之间的区别是 URL()构造函数不是Node它也没有附加到特定的 Document 对象,因此没有baseURI可以挂接。
因此,要使 URL()构造函数的行为与锚点 元素相同,您需要传递一个 baseURI 作为second argument of the constructor。
这意味着,只要生成的 URI 是有效的,在文档new URL(uri, document.baseURI)
中将返回与Object.assign(document.createElement('a'), {href: uri})
相同的URL属性。
现在,在Worker中,我们仍然也无法访问 Node 的 baseURI ,并且还不清楚您要挂接哪个对象。
在大多数情况下,您可以简单地使用self.location.href
作为基本URI,而如果要获取同源资源,则实际上可能就是您想要的,但是如果您确实从blobURL初始化了Worker, ,您可能必须从主要范围传递它,就像我在StackSnippet®的过度保护的iframe中所做的那样。
// 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>