跨域通信?

时间:2011-11-11 21:32:15

标签: javascript ajax json jsonp

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

如果我要做一个通过脚本元素更新每一秒的聊天系统,那资源太重了吗?如果我确实使用jsonp,我应该为新请求更新一个脚本元素,还是每次都添加新请求?

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

2 个答案:

答案 0 :(得分: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() - 用于发送请求。

答案 1 :(得分:0)

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

之后,您将能够从脚本中进行ajax调用而没有任何问题。

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

希望这有帮助。