javascript - 跨域通信?

标签 javascript ajax json jsonp

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

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

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

最佳答案

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

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

Origin: http://www.webiste.com

如果服务器决定应该允许该请求,它会发送一个 Access-Control-Allow-Origin header ,以回显发送的相同来源或“*”(如果它是公共(public)资源)。例如:

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

如果缺少此 header ,或者来源不匹配,则浏览器将拒绝该请求。如果一切顺利,浏览器就会处理请求。请注意,请求和响应均不包含 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 对象具有足够相似的接口(interface),因此该模式运行良好。常用的接口(interface)属性/方法有:

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

关于javascript - 跨域通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8100224/

相关文章:

javascript - 了解 $.Ajax 上的 JQuery 文档

javascript - 如何在react.js中使用json

c# - .NET WCF 服务获取 Blob 的 JSON 列表

javascript - Highcharts 未在grails View 中呈现

javascript 对象 - 检索子类变量

javascript - Joomla 中包含 HTML 的工具提示

jQuery 不适用于 Ajax 返回的代码

json - 网站创建失败,找不到服务器场 Azure Powershell

javascript - 为什么在支持 UnderscoreJS 的重命名函数中使用 apply ?

javascript - CKEDITOR:如何转换所有 html 实体