ajax跨域

什么是跨域?

如果两个站点www.a.com想向www.b.com请求数据就出现了因为域名不一致导致的跨域问题。即使是域名相同,如果端口不同的话也

是会存在跨域问题(这种原因js是只能袖手旁观了)。判断是否跨域仅仅是通过window.location.protocol+window.location.host来判断例如http://www.baidu.com.

js解决跨域问题几种方案?

1、document.domain+iframe

对于主域相同而子域不同的请求可以使用域名+iframe作为解决办法。具体思想是假如有两个域名下的不同ab文件www.a.com/a.html

以及hi.a.com/b.html,我们可以在两个html文件中加上document.domain="a.com",之后通过在a文件中创建一个iframe去控制iframe

的contentDocument,这样两个文件就可以对话了。

举例如下:

www.a.com上的a.html文件中

    

1 document.domain="a.com";var selfFrame=document.createElement("iframe");
2 selfFrame.src="http://hi.a.com/b.html";
3 selfFrame.style.display="none";
4 document.body.appendChild(selfFrame);
5 selfFrame.onload=function(){
6    var doc=selfFrame.contentDocument||selfFrame.contentWindow.document;//得到操作b.html权限
7    alert(doc.getElementById("ok_b").innerHTML());//具体操作b文件中元素
8 }
View Code

 

hi.a.com上的b.html文件中

document.domain="a.com";

问题:1、安全性,当一个站点(hi.a.com)被攻击后,另一个站点(www.a.com)会引起安全漏洞。2、如果一个页面中引入多个

iframe,要想能够操作所有iframe,必须都得设置相同domain。

2、动态创建script(传说中jsonp方式)

浏览器默认禁止跨域访问,但不禁止在页面中引用其他域名的js文件,并且可以执行引入js文件中的方法等,根据这点我们可以通

过创建script节点方法来实现完全跨域的通信。

实现步骤为:

a.在请求发起方页面动态加载一个script,script的url指向接收方的后台,该地址返回的javascript方法会被发起方执行,url可以传参并仅支持get提交参数。

b.加载script脚本时候调用跨域的js方法进行回调处理(jsonp)。

举例如下:

发起方

 1 function uploadScript(options){
 2 
 3     var head=document.getElementsByTagName("head")[0];
 4 
 5     var script=document.createElement("script");
 6 
 7     script.type="text/javasctipt";
 8 
 9     options.src += '?callback=' + options.callback;
10 
11     script.src=options.src;
12 
13     head.insertBefore(script,head.firstChild);
14 
15 }
16 
17 function callback(data){}
18 
19 window.onload=function(){//调用
20 
21     uploadScript({src:"http://e.com/xxx/main.ashx",callback:callback})
22 
23 }

 

接收方:

接收方只需要返回一个执行函数,该执行函数就是请求中的callback并赋参数。

3、使用html5的postMessage:

html5新功能有一个就是跨文档消息传输,如今大部分浏览器都已经支持并使用(包括ie8+),其支持基于web的实时消息传递并且不存在跨域问题。postMessage一般会跟iframe一起使用。

举例如下:

父页面:

<iframe id="myPost" src="http//www.a.com/main.html"></iframe>

window.onload=function(){

    document.getElementById("myPost").contentWindow.postMessage("显示我","http://www.a.com")

    //第二个参数表示确保数据发送给适合域名的文档

}

 

a.com/main.html页面:

 1 window.addEventListener("message",function(event){
 2 
 3     if(event.origin.indexOf("a.com")>-1){
 4 
 5         document.getElementById("textArea").innerHTML=event.data;
 6 
 7     }
 8 
 9 },false)
10 
11 <body>
12 
13     <div>
14 
15         <span id="textArea"></span>
16 
17     </div>
18 
19 </body>

 

这样在父页面加载完成后main.html页面的textArea部分就会显示"显示我"三个字

 

-------------------------------------------------------------------------------------------------

ajax方法封装code:

  1 ZIP_Ajax.prototype={
  2 
  3     request:function(url options){
  4 
  5         this.options=options;
  6 
  7         if(options.method=="jsonp"){//跨域请求
  8 
  9             return this.jsonp();
 10 
 11         }
 12 
 13         var httpRequest=this.http();
 14 
 15         options=Object.extend({method: 'get',
 16 
 17             async: true},options||{});
 18 
 19         
 20 
 21         if(options.method=="get"){
 22 
 23             url+=(url.indexOf('?')==-1?'?':'&')+options.data;
 24 
 25             options.data=null;
 26 
 27         }
 28 
 29         httpRequest.open(options.method,url,options.async);
 30 
 31         if (options.method == 'post') {
 32 
 33             httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
 34 
 35         }
 36 
 37         httpRequest.onreadystatechange = this._onStateChange.bind(this, httpRequest, url, options);
 38 
 39         httpRequest.send(options.data || null);//get请求情况下data为null
 40 
 41         return httpRequest;
 42 
 43     },
 44 
 45     jsonp:function(){
 46 
 47         jsonp_str = 'jsonp_' + new Date().getTime();
 48 
 49         eval(jsonp_str + ' = ' + this.options.callback + ';');        
 50 
 51         this.options.url += '?callback=' + jsonp_str;
 52 
 53         for(var i in this.options.data) {
 54 
 55             this.options.url += '&' + i + '=' + this.options.data[i];
 56 
 57         } 
 58 
 59         var doc_head = document.getElementsByTagName("head")[0],
 60 
 61             doc_js = document.createElement("script"),
 62 
 63             doc_js.src = this.options.url;
 64 
 65         doc_js.onload = doc_js.onreadystatechange = function(){
 66 
 67              if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete"){
 68 
 69                   //清除JS
 70 
 71                   doc_head.removeChild(doc_js);            
 72 
 73                 }
 74 
 75             }      
 76 
 77             doc_head.appendChild(doc_js);
 78 
 79     },
 80 
 81     http:function(){//判断是否支持xmlHttp
 82 
 83         if(window.XMLHttpRequest){
 84 
 85             return new XMLHttpRequest();
 86 
 87         }
 88 
 89         else{
 90 
 91             try{
 92 
 93                 return new ActiveXObject('Msxml2.XMLHTTP')
 94 
 95             }
 96 
 97             catch(e){
 98 
 99                 try {
100 
101                     return new ActiveXObject('Microsoft.XMLHTTP');
102 
103                 } catch (e) {
104 
105                     return false;
106 
107                 }
108 
109             }
110 
111         }
112 
113     },
114 
115     _onStateChange:function(http,url,options){
116 
117         if(http.readyState==4){
118 
119             http.onreadystatechange=function(){};//重置事件为空
120 
121             var s=http.status;
122 
123             if(typeof(s)=='number'&&s>200&&s<300){
124 
125                 if(typeof(options.success)!='function')return;
126 
127                 var format=http;
128 
129                 if(typeof(options.format)=='string'){//判断请求数据格式
130 
131                     switch(options.format){
132 
133                         case 'text':
134 
135                             format=http.responseText;
136 
137                             break;
138 
139                         case 'json':
140 
141                             try{
142 
143                                 format=eval('('+http.responseText+')');
144 
145                             }
146 
147                             catch (e) {
148 
149                                 if (window.console && console.error) console.error(e);
150 
151                             }
152 
153                             break;
154 
155                         case 'xml':
156 
157                             format=http.responseXML;
158 
159                             break;
160 
161                     }
162 
163                 }
164 
165             options.success(format);//成功回调
166 
167             }
168 
169             else {//请求出问题后处理
170 
171                 if (window.closed) return;
172 
173                 if (typeof (options.failure) == 'function') {
174 
175                     var error = {
176 
177                         status: http.status,
178 
179                         statusText: http.statusText
180 
181                     }
182 
183                     //    判断是否是网络断线或者根本就请求不到服务器
184 
185                     if (http.readyState == 4 && (http.status == 0 || http.status == 12030)) {
186 
187                         //
188 
189                         error.status = -1;
190 
191                     }
192 
193                     options.failure(error);
194 
195                 }
196 
197             }
198 
199         }  
200 
201     }
202 
203 };

 

-------------------------------------------------------------------------------------------------

使用方法:

ajax调用举例:

 1 var myAjax=new ZIP_Ajax("http://www.a.com/you.php",{
 2 
 3     method:"get",
 4 
 5     data:"key=123456&name=yuchao",
 6 
 7     format:"json",
 8 
 9     success:function(data){
10 
11         ......
12 
13     }
14 
15 })

 

跨域请求调用举例:

var jsonp=new ZIP_Ajax("http://www.a.com/you.php",{

    method:"jsonp",

    data:{key:"123456",name:"yuchao"},

    callback:function(data){

        ......

    }

})

 

转载自:玉超csdn Blog

posted @ 2014-02-25 09:15  浅笑esmiler  阅读(144)  评论(0)    收藏  举报