跨域JavaScript的替代方案是什么?

3

目前我依靠代理脚本来处理同源策略问题。这种方法速度慢,会增加开销。更不用说,JavaScript也无法渲染。

是否有其他可行的替代方案?

5个回答

5
如果您可以在调用JavaScript代码的服务中提供回调函数名称作为参数,则可以将脚本标签附加到文档中,并将src属性指向服务调用。否则,您就没办法了。

这通常被称为JSONP - 或带填充的JSON - 更进一步:带填充的JavaScript对象表示法。 :) - Alex Sexton
请注意,在Internet Explorer中,大型脚本可能会导致内存泄漏,即在删除脚本标记后不释放的大量内存使用。如果您每个页面视图只进行1或2次调用,则这不是一个主要问题,但是如果您希望页面保持打开状态并在长时间内进行调用,则可能会收到来自计算机速度极慢的用户的投诉 :) - Andy E

2

使用iframe并尝试使用window.postMessage(message, origin)(从iframe中是parent.postMessage,从顶层页面是iframeElement.contentWindow.postMessage)适用于所有最新的主流浏览器(Firefox,IE,Safari,Chrome等),对于旧浏览器则改变/轮询window.name


1

哦,亲爱的,我认为你正在寻找的解决方案是使用IFRAME。然而,IFRAME方法既需要思维上的努力,也需要技术上的努力。我建议你从这个指南开始:

使用IFrame进行跨域通信

另一种方法是使用脚本标签和JSON异步地从另一个服务器获取数据:

<script src="http://remotesite.com/path/to/script/blah.js"></script>

你可以创建一个新的SCRIPT标签元素来传递和加载数据并附加到DOM,或将标记插入到元素的innerHTML中。
我相信你可以找到一些详细的示例和实现方法,但是有一件事情你应该关注,在使用新的SCRIPT方法时要避免添加太多DOM。这可能会对你有所帮助,并为你提供一个起点:
function require (url, callback) {
    if (!isScriptLoaded(url)) { 
        document.write('<script src="' + url + '" type="text/javascript" charset="utf-8"><\/script>');

        if (callback) {
            callback();
        }
    }
}

function isScriptLoaded(src) {
    var scriptsLoaded =  {};
    var scriptTags    = document.getElementsByTagName("script");

    for (var i = 0, script; script = scriptTags[i]; i++) {
        if (script.src) { 
            scriptsLoaded[script.src] = 1;
        }
    };

    if (scriptsLoaded[src]) {
        return true; 
    }

    return false;
}

(未经测试,但应该可行!)

无论如何 - 祝好运。


是的。iframe加载一个外部页面,其中需要运行一些JavaScript代码。但是由于单一原始策略,这是不被允许的。因此,只能依赖代理来实现,但这并不是最优或高效的解决方案。 - dooli
很遗憾,没有具体的信息我无法正确回答这个问题。在我看来,这不是一个问题,但我的解决方案是否有效取决于您的后端设置等。根据您的评论:
  • iframe加载外部页面
  • iframe URL可以包含参数以指示JS回调和参数
  • 本地iframe JS解释此并继续执行
显然,如果涉及某些动态JS或传递大量值,则此方法将无效...我有印象这对您没有帮助,因为您有更深层次的需求,但它可能会帮助其他人。
- donohoe

1

JSON-P 对于这种情况非常理想。如果你正在使用 jQuery 或类似的 JavaScript 库,那么你的工作会更加容易:

http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback

当然,使用哪种方案取决于你要完成什么任务,需要使用JSON-P、隐藏的iframe、postMessage、Flash代理或其他任何奇特的解决方案。


1

如果您控制两个域并且只关心Firefox 3.5+,则可以使用XMLHttpRequest对象,并使用访问控制设置权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接