我在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
属性加载的脚本。
我还有哪些其他方法可以解决这个问题?
答案 0 :(得分:2)
您需要发出一个Ajax请求...如果它与该页面的域相同,它将正常加载,如果服务器发送了缓存标头,它应该使用现有的副本。
如果它在另一个域上,您将需要CORS头(在支持的位置)和/或JSONP加载器。
答案 1 :(得分:1)
如果您尝试直接通过标记包含自定义脚本,那么它将无法解析,您将无法获得内部HTML。
我建议使用JSONP风格的方法。首先定义一个全局处理函数,例如
// myproglang.js
window.registerSource = function(source) {
myProgLang.eval(source);
}
然后在源文件中,将代码包装在对该函数的调用中:
// source.mypl
registerSource("\
Dim foo as Integer;\
")
它有点难看,因为它需要文本文件来转义换行符以保持字符串文字,但除了使用XHR之外,这是我能想到的唯一可行的解决方案。
您总是可以为这种“语言”编写一个编译步骤,用"\n"
替换"\\\n"
并将源包装在registerSource()调用中。只要它是透明的,它就是一个可行的选择。
答案 2 :(得分:1)