跨域HTTP请求
作为同源策略的一部分,XMLHttpRequest对象通常仅可以发起和文档具有相同服务器的HTTP请求。这个限制关闭安全漏洞,但它笨手笨脚并且也阻止了大量合适使用的跨域请求。可以在<from>和<iframe>元素中使用跨域url,而且浏览器显示最终的跨域文档。但因为同源策略,浏览器不允许原始脚本查找跨域文档的内容。(注意:<script>元素并未真正受限于同源策略,它加载并执行任何来源的脚本。跨域请求的灵活性使用<script>元素成为取代XMLHttpRequest的主流Ajax传输协议)
XHR2通过在HTTP响应中选择发送合适的CORS(Cross-Origin Resource Sharing 跨域资源共享)允许跨域访问网站。目前firefox、safari、chrome的当前版本都支持CORS,而IE8通过XDomainRequest对象支持它。使用它不需要额外的编码,如果浏览器支持XMLHttpRequest的CORS且实现跨域请求的网站决定使用CORS允许跨域请求,那么同源策略不放宽而跨域请求就会正常工作。
虽然不需要额外的编码,但还是需要了解一些细节:
如果给XMLHttpRequest的open()方法输入用户名和密码,那么它们绝对不会通过跨域请求发送。
跨域请求通常也不会包含其他任何的用户证书:cookie和HTTP身份验证令牌通常不会作为请求内容部分发送且任何作为跨域响应来接收的cookie都会丢失。如果跨域请求需要这几种凭证才能成功,那么必须用send()发送请求前设置XMLHttpRequest的withCredentials属性为true。
这样做不常见,但测试withCredentials的存在是测试浏览器是否支持CORS的一种方法。
例:使用HEAD和CORS请求链接详细信息:
whenReady(function(){
var supportsCORS = (new XMLHttpRequest()).withCredentials!==undefined;
var links = document.getElementsByTagName('a);
for(var i=0;i<links.length;i++){
var link = links[i];
if(!link)continue;
if(link.title)continue;
if(link.host!==location.host || link.protocol!==location.protocol){
link.title ="站外链接";
if(!supportsCORS)continue;
}
if(link.addEventListener) link.addEventListener("mouseover",mouseoverHandler,false)
else link.attachEvent("onmouseover",mouseoverHandler)
}
function mouseoverHandler(e){
var link = e.target || e.srcElement;
var url = link.href;
var req = new XMLHttpRequest();
req.open("HEAD",url);
req.onreadystatechange = function(){
if(req.readyState!==4)return;
if(req.state==200){
var type = req.getResponseHeader("Contet-Type");//获取链接的详细的情况
var size = req.getResponseHeader("Content-Length");
var date =request.getResponseHeader("Last-Modified");
link.title = "类型"+type+"\n"+"大小"+size+"\n"+"时间"+date;
}else{
if(!link.title) link.title ="Couldn't fetch details :\n"+req.status+" "+req.statusText;
}
}
req.send(null);
if(link.removeEventListener)
link.removeEventListener("mouseover",mouseoverHandler,false);
else
link.detachEvent("onmouseover",mouseoverHandler)
}
})