【问题标题】:Get the content of a cross domain script tag获取跨域脚本标签的内容
【发布时间】:2013-02-23 11:06:57
【问题描述】:

我在 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 属性访问。

我还有哪些其他选择可以解决这个问题?

【问题讨论】:

  • 你有没有看过其他人是如何做到这一点的,例如咖啡脚本?如果也没有处理它,那么它可能不值得费心(尽管我承认看看是否有一个方便的解决方案很有趣)。
  • @FelixKling - CoffeeScript uses AJAX 但这并不能解决跨域问题。
  • 跨域 XMLHttpRequest / XDomainRequest 有什么问题?适用于所有现代浏览器。

标签: javascript cross-domain requirejs innerhtml script-tag


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

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

    【讨论】:

      【解决方案3】:

      herehere 已经提出过这个问题。

      基本上共识是:

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

      注意事项

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

      可以使用来自脚本主机的Access-Control-Allow-Origin: * 标头来修复跨域问题。

      【讨论】:

        猜你喜欢
        • 2012-08-15
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多