如何让通过 AJAX 加载的 JS 文件识别全局函数?

How do I get a global function recognized by my JS file loaded through AJAX?

我对 Javascript 中的作用域以及如何识别全局函数感到困惑。在我的页面上我有

<script src="base64.js"></script>

定义。然后在另一个文件中,我有

var xhr = new XMLHttpRequest;
...
        var full = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '');
            alert(Base64.decode("abc"));
        xhr.open("get", full + "myotherfile.js", true);
        xhr.send()

警报执行没有问题。然而,在 "mytoherfile.js" 中对 Base64 class 的引用会导致 RerefernceError。所以在我的 myotherfile.js 顶部,我尝试了

import {Base64} from 'base64';

但这会导致 "Uncaught SyntaxError: Unexpected token {" 错误。在通过 AJAX 加载的 JS 文件中识别我的全局函数的正确方法是什么?

编辑:远程加载的JS文件使用

加载
this.worker = new Worker(xhrResponseText);

在老式(非模块)javascript 文件中,全局变量隐含在 window 上。所以在第一个例子中,Base64.decode("abc")window.Base64.decode("abc") 相同。然而,在模块中,情况并非如此。如果要访问 window 上的全局变量,则必须显式完成。

在模块中,尝试将对 Base64 的引用更改为 window.Base64

旁注:如果 base64.js 文件与基本脚本标签导入一起使用,则无法像您所做的那样将其作为 es6 模块导入 (import {Base64} from 'base64';)。您可以阅读有关如何导入模块的更多信息 here!

希望对您有所帮助!

更新

为清楚起见,这里有几个例子。基本上,您放在花括号 ({ Base64}) 中的内容必须从正在导入的脚本中导出,而不是放在 window.

<script src=".../base64.js"></script>

<script>
  // both are accessible this way because this is NOT a module
  // and global variables are assumed to be on the window.
  console.log(Base64);
  console.log(window.Base64);
</script>

<script type="module">
  // Will not work:
  // import { Base64 } from ".../base64.js
  // import { window.Base64 } from ".../base64.js

  // The same as importing view the script tag
  // (not needed because the script tag already imported it)
  // import ".../base64.js"

  // the "global variable" is accessible on the window
  console.log(window.Base64)
</script>

主页中加载的脚本在 web workers 中不可用,您必须使用 importScripts 而不是导入命令

导入它们
importScripts("base64.js");

问题出在您所指的路径上。这是类型模块中的有效路径。

// Supported:
import {foo} from 'https://jakearchibald.com/utils/bar.js';
import {foo} from '/utils/bar.js';
import {foo} from './bar.js';
import {foo} from '../bar.js';

// Not supported:
import {foo} from 'bar.js';
import {foo} from 'utils/bar.js';

尝试直接引用路径。像这样

import {addTextToBody} from '../../someFolder/someOtherfolder/utils.js';

这里是有效的路径名

Starts with ./  :- same folder
Starts with ../ :- Parent folder
Starts with ../../ :- above parentfolder