51 lines
1.8 KiB
JavaScript
51 lines
1.8 KiB
JavaScript
const type = 'application/javascript';
|
||
|
||
/**
|
||
*
|
||
* @param {string} originalWorkerUrl
|
||
* @param {{
|
||
* useBlob?: boolean
|
||
* skipSameOrigin?: boolean
|
||
* }} options
|
||
* @returns {Promise<string>}
|
||
*/
|
||
async function getCrossOriginWorkerURL (originalWorkerUrl, options = {}) {
|
||
const skipSameOrigin = options.skipSameOrigin || true;
|
||
const useBlob = options.useBlob || true;
|
||
|
||
// 本来就是同源的,不需要额外进行处理,直接返回
|
||
if (!originalWorkerUrl.includes('://') || originalWorkerUrl.includes(window.location.origin)) {
|
||
return originalWorkerUrl;
|
||
}
|
||
|
||
// 获取 worker 的 js 代码
|
||
const res = await fetch(originalWorkerUrl);
|
||
const workerJsCode = await res.text();
|
||
|
||
// worker 所在的文件夹 url
|
||
const workerPath = new URL(originalWorkerUrl).href.split('/');
|
||
workerPath.pop();
|
||
|
||
// 给 importScripts 的每一个引入的js文件增加 workerPath 组成绝对路径
|
||
const importScriptsFix = `const _importScripts = importScripts;
|
||
const _fixImports = (url) => new URL(url, '${workerPath.join('/') + '/'}').href;
|
||
|
||
importScripts = (...urls) => _importScripts(...urls.map(_fixImports));
|
||
`;
|
||
|
||
// 以 MIME 协议组成 blob,从而进行装载
|
||
let resultURL = `data:${type},` + encodeURIComponent(importScriptsFix + workerJsCode);
|
||
if (useBlob) {
|
||
// 在外面再套一层 importScripts,这样第二次请求得到的 worker 就不是 blob worker 了
|
||
// 直接使用 createObjectURL 请求一个 worker 的源码是不行的,因为这样得到的 blob worker
|
||
// 会有原本 worker 的 feature 无法使用
|
||
resultURL = URL.createObjectURL(
|
||
new Blob([`importScripts("${resultURL}")`], { type })
|
||
);
|
||
}
|
||
return resultURL;
|
||
}
|
||
|
||
export {
|
||
getCrossOriginWorkerURL
|
||
} |