最近在网络上看了很多JS跨域访问的解决方案。。比较了一下,大致上有这么两种:
第一个是使用内嵌的iframe,由于iframe能够访问外部域,因此,便实现了一种简单的跨域访问。但是这里存在着一个问题,那就ParentWindow和childWindow之间不能直接进行交互,因为在跨域的情况下,由于安全性的原因,这种交互是被拒绝的。。这时候,人们便想到了使用anchor hash来实现。因为改变一个网页的anchor hash并不会使网页重新加载,,从而使网页的状态得到了保持。而网页本身可以通过一个计时器侦听自己hash的变化,从而改变自己的状态。。说白了,其实就是使用anchor hash来进行跨域的交互。。
这种方法现在用的很少,下面介绍另一种比较流行的办法:JSONP
这种方式实际上是使用script标签来进行跨域的访问。它的原理实质上就是通过script标签来对javascript文档的动态解析来说实现。。当我们要求实现AJAX跨域访问时,必须忘掉方便的XMLHttpRequest,而只使用动态生成的script,下面的一个例子是对JSONP方法的一个包装,来模拟ajax:(使用script的一个限制是它只支持get请求,这就限制了它只能传递少量的数据)
var XssHttpRequestCount=0; var XssHttpRequest=function(){ this.requestID='XSS_HTTP_REQUEST_'+(++XssHttpRequestCount); } XssHttpRequest.prototype={ url:null, scriptObject:null, responseJSON:null, status:0, readyState:0, timeout:30000, onreadystatechange:function(){}, setReadyState:function(newReadyState){ if(this.readyState<newReadyState||newReadyState==0){ this.readyState=newReadyState; this.onreadystatechange(); } }, open:function(url,timeout){ this.timeout=timeout||3000; this.url=url +((url.indexOf('?')!=-1)?'&':'?') +'XSS_HTTP_REQUEST_CALLBACK=' +this.requestID+'_CALLBACK'; this.setReadyState(0); }, send:function(){ var requestObject=this; this.scriptObject=document.createElement('script'); this.scriptObject.setAttribute('id',this.requestID); this.scriptObject.setAttribute('type','text/javascript'); var timeoutWatcher=setTimeout(function(){ window[requestObject.requestID+'_CALLBACK']=function(){}; requestObject.scriptObject.parentNode.removeChild(requestObject.scriptObject); reqeustObject.status=2; requestObject.statusText='Timeout after '+requestObject.timeout+' milliseconds.'; requestObject.setReadyState(2); requestObject.setReadyState(3); requestObject.setReadyState(4); },this.timeout); window[this.requestID+'_CALLBACK']=function(JSON){ clearTimeout(timeoutWatcher); requestObject.setReadyState(2); requestObject.setReadyState(3); requestObject.responseJSON=JSON; requestObject.status=1; requestObject.statusText='Loaded'. requestObject.setReadyState(4); } this.setReadyState(1); this.scriptObject.setAttribute('src',this.url); var head=document.getElementsByTagName('head')[0]; head.appendChild(this.scriptObject); } } function getXssRequestObject(url,options){ var req=new XssHttpRequest(); options=options||{}; options.timeout=options.timeout||30000; req.onreadystatechange=function(){ //这里模拟ajax中的请求状态 switch(req.readyState){ case 1: //载入中 if(options.loadListener){ options.loadListener.apply(req,arguments); } break; case 2: //载入完成 if(options.loadedListener){ options.loadedListener.apply(req,arguments); } break; case 3: //交互 if(options.interactiveListener){ options.interactiveListener.apply(req,arguments); } break; case 4: //完成 if(req.status==1){ if(options.completeListener){ options.completeListener.apply(req,arguments); } } else{ if(options.errorListener){ optiosn.errorListener.apply(req,arguments); } } break; } }; req.open(url,options.timeout); return req; } function xssRequest(url,options){ var req=getXssRequestObject(url,options); return req.send(null); }