如何检查 URL 是否与当前页面 and/or worker 同源
How to check if a URL is same origin as current page and/or worker
这里有一个类似的问题
javascript How to check if a URL is same origin as current page?
遗憾的是,它没有指定答案必须在页面和工作人员中都有效,因此 none 的答案在工作人员中有效。
特别是我正在尝试使用 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
对象似乎不像锚点那样处理相关资源。
URL()构造函数和锚点元素的区别在于URL() 构造函数不是节点,也不附加到特定的 Document 对象,因此没有 baseURI 它可以挂上。
所以你需要什么才能使 URL() 构造函数的行为与锚点相同 元素是传递一个 baseURI 作为 second argument of the constructor.
这意味着在文档 new URL(uri, document.baseURI)
中 return 具有与 Object.assign(document.createElement('a'), {href: uri})
相同的 URL 属性,只要 URI 生成的是有效的。
现在,在 Worker 中,我们仍然无法访问 Node 的 baseURI,也不清楚是哪个你想上钩。
在大多数情况下,您可以简单地使用 self.location.href
作为基本 URI,如果您要获取同源资源,这实际上可能是您想要的,但是如果您确实从一个 blobURL,您可能必须从主作用域传递它,就像我在 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>
这里有一个类似的问题
javascript How to check if a URL is same origin as current page?
遗憾的是,它没有指定答案必须在页面和工作人员中都有效,因此 none 的答案在工作人员中有效。
特别是我正在尝试使用 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
对象似乎不像锚点那样处理相关资源。
URL()构造函数和锚点元素的区别在于URL() 构造函数不是节点,也不附加到特定的 Document 对象,因此没有 baseURI 它可以挂上。
所以你需要什么才能使 URL() 构造函数的行为与锚点相同 元素是传递一个 baseURI 作为 second argument of the constructor.
这意味着在文档 new URL(uri, document.baseURI)
中 return 具有与 Object.assign(document.createElement('a'), {href: uri})
相同的 URL 属性,只要 URI 生成的是有效的。
现在,在 Worker 中,我们仍然无法访问 Node 的 baseURI,也不清楚是哪个你想上钩。
在大多数情况下,您可以简单地使用 self.location.href
作为基本 URI,如果您要获取同源资源,这实际上可能是您想要的,但是如果您确实从一个 blobURL,您可能必须从主作用域传递它,就像我在 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>