我正在用 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/