1

我在 JavaScript 中创建了一种新的编程语言,我希望用户能够将它包含在他们的网页中,就像使用该script标签的任何其他脚本一样:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <title>My Prog Lang</title>
        <script src="scripts/myProgLang.js"></script>
        <script type="text/my-prog-lang" src="scripts/index.mypl"></script>
    </head>
</html>

这个想法是myProgLang.js获取所有脚本的内容并执行它们:

window.addEventListener("DOMContentLoaded", function () {
    var scripts = document.querySelector('script[type="text/my-prog-lang"]');
    var length = scripts.length;

    for (var i = 0; i < length; i++) {
        var script = scripts[i];
        var src = script.getAttribute("src");
        var content = AJAX.getSync(src);
        myProgLang.eval(content);
    }
}, false);

这种方法的明显问题(除了进行同步 AJAX 调用之外)是不同域上的脚本违反了相同的源策略。

显而易见的解决方案是使用RequireJS之类的脚本加载器,使用文本插件将脚本加载为纯文本。

但是我不想仅仅为了这个任务而包含整个 RequireJS 框架。所以我做了一些挖掘,找到了这个答案:https ://stackoverflow.com/a/4927418/783743

根据上面的答案:

脚本元素的 innerHTML 属性应该以字符串形式提供脚本内容,前提是脚本元素是:

  • 内联脚本,或
  • 脚本已加载(如果使用 src 属性)

不幸的是,这不起作用(至少在 Opera 上)。使用属性加载的脚本src无法使用属性访问innerHTML

我还有什么其他选择来解决这个问题?

4

3 回答 3

2

您需要发出 Ajax 请求...如果它与页面相同的域,它将正常加载,如果服务器发送缓存标头,它应该使用现有副本。

如果它在另一个域上,您将需要 CORS 标头(如果支持)和/或 JSONP 加载器。

于 2013-03-01T00:37:09.570 回答
1

如果您尝试通过标签直接包含您的自定义脚本,那么它将无法解析,并且您将无法获取 的 innerHTML。

我建议使用 JSONP 风格的方法。首先定义一个全局处理函数,例如

// myproglang.js

window.registerSource = function(source) {
    myProgLang.eval(source);
}

然后在您的源文件中,将您的代码包装在对该函数的调用中:

// source.mypl
registerSource("\
Dim foo as Integer;\
")

这有点难看,因为它需要文本文件转义换行符以维护字符串文字,但除了使用 XHR 之外,这是我能想到的唯一可行的解​​决方案。

您总是可以为这种“语言”编写一个编译步骤,在 registerSource() 调用中替换并包装源代码"\n""\\\n"只要它是透明的,它就是一个可行的选择。

于 2013-02-26T00:19:50.373 回答
1

这个问题已经在这里这里被问过了。

基本上共识是:

  • 如果脚本是内联的,则可以使用script.innerHTML
  • 如果它不是内联的,则只有在发出另一个 ajax 请求时才能访问它。(显然你可能会遇到跨域问题)

笔记

如果您的 HTTP 标头配置正确,您应该能够从浏览器的缓存中获取脚本,因此速度会很快。

跨域问题可以通过Access-Control-Allow-Origin: *脚本主机的标头来解决。

于 2013-02-27T15:29:51.120 回答