【问题标题】:Cross domain communication?跨域通信?
【发布时间】:2011-12-27 08:45:50
【问题描述】:

我正在用 javascript 构建一个小应用程序,以便在我不拥有的网站上使用。该应用程序包含一些可以稍微改变网站的选项。我希望能够添加登录系统和聊天。由于跨域策略,我知道我不能做常规的 ajax。我知道的唯一另一件事是通过将脚本元素附加到网页来生成 jsonp。

如果我要创建一个通过脚本元素每秒更新一次的聊天系统,那会不会占用太多资源?如果我确实使用 jsonp,我应该为新请求更新一个脚本元素,还是每次都追加新的?

jsonp 甚至可以解决这个问题吗?

【问题讨论】:

    标签: javascript ajax json jsonp


    【解决方案1】:

    将使用您的应用程序的服务器需要将您的应用程序的域添加到跨域策略文件中。这通常是一个位于 Web 根目录中的 XML 文件,但确切的性质取决于该服务器是 .NET、PHP 等。

    之后,您将能够毫无问题地从脚本中进行 ajax 调用。

    IMO,动态添加脚本标签是自找麻烦,特别是如果 DOM 不知道你在做什么。

    希望这会有所帮助。

    【讨论】:

    • 认真的吗?我认为是浏览器和服务器阻止了请求。你有更多关于我如何做到这一点的信息吗?
    • 如果这对您没有帮助,请告诉我,我会尽力帮助您完成剩下的工作。
    • 那是 Flash 的,有 javascript 的吗?
    • 嘿 Walkerneo——也许这个 tut 能帮上忙:jquery-howto.blogspot.com/2009/04/…
    【解决方案2】:

    跨源资源共享 (CORS) 是一个 W3C 工作草案,它定义了浏览器和服务器在跨源访问资源时必须如何通信。 CORS 背后的基本思想是使用自定义 HTTP 标头来允许浏览器和服务器充分了解彼此,以确定请求或响应是成功还是失败。

    对于一个简单的请求,即使用 GET 或 POST 且没有自定义标头且正文为 text/plain 的请求,发送的请求带有一个名为 Origin 的额外标头。 Origin 标头包含请求页面的来源(协议、域名和端口),以便服务器可以轻松确定是否应该提供响应。示例 Origin 标头可能如下所示:

    Origin: http://www.webiste.com
    

    如果服务器决定允许该请求,它会发送一个 Access-Control-Allow-Origin 标头来回显发送的相同来源,如果它是公共资源,则返回“*”。例如:

    Access-Control-Allow-Origin: http://www.webiste.com
    

    如果缺少此标头,或者来源不匹配,则浏览器将拒绝该请求。如果一切正常,则浏览器会处理该请求。请注意,请求和响应都不包含 cookie 信息。

    前面提到的所有浏览器都支持这些简单的请求。 Firefox 3.5+、Safari 4+ 和 Chrome 都支持通过 XMLHttpRequest 对象使用。当尝试打开不同来源的资源时,此行为会自动触发,无需任何额外代码。例如:

    var xhr = new XMLHttpRequest();
    xhr.open("get", "http://www.webiste.com/some_resource/", true);
    xhr.onload = function(){  //instead of onreadystatechange
        //do something
    };
    xhr.send(null);
    

    要在 Internet Explorer 8 中执行相同操作,您需要以相同的方式使用 XDomainRequest 对象:

    var xdr = new XDomainRequest();
    xdr.open("get", "http://www.webiste.com/some_resource/");
    xdr.onload = function(){
        //do something
    };
    xdr.send();
    

    Mozilla 团队在他们关于 CORS 的帖子中建议您应该检查 withCredentials 属性是否存在,以确定浏览器是否通过 XHR 支持 CORS。然后你可以结合 XDomainRequest 对象的存在来覆盖所有浏览器:

    function createCORSRequest(method, url){
        var xhr = new XMLHttpRequest();
        if ("withCredentials" in xhr){
            xhr.open(method, url, true);
        } else if (typeof XDomainRequest != "undefined"){
            xhr = new XDomainRequest();
            xhr.open(method, url);
        } else {
            xhr = null;
        }
           return xhr;
        }
    
    var request = createCORSRequest("get", "http:/www.webiste.com/");
    if (request){
        request.onload = function(){
            //do something with request.responseText
        };
        request.send();
    }
    

    Firefox、Safari 和 Chrome 中的 XMLHttpRequest 对象与 IE 中的 XDomainRequest 对象具有足够相似的接口,因此该模式运行良好。常用的接口属性/方法有:

    • abort() - 用于停止已经在进行的请求。
    • onerror - 使用而不是 onreadystatechange 来检测错误。
    • onload - 使用而不是 onreadystatechange 来检测成功。
    • responseText - 用于获取响应内容。
    • send() – 用于发送请求。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多