ajax跨域访问 JQuery 的跨域方法
2012-10-23 13:07
197 查看
JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。
下面开始贴出方法。
//跨域(可跨所有域名)
注意,getregion.aspx中,在输出JSON数据时,一定要用Request.QueryString["jsoncallback"],将获取的内容放到返回JSON数据的前面,假设实际获取的值为42342348,那么返回的值就是42342348([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}])
因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。
具体getJSON的使用说明,请参考JQUERY手册。
下面一个是跨域执行的真实例子:
转载自csdn:http://blog.csdn.net/misswuyang/archive/2009/10/23/4718737.aspx
jQuery跨域原理:
浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;
看下面的例子:
这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON
withpadding上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?
貌似并没有<Script>标记的出现!?OKay,翻看源码来看:
页面调用的是getJSON:
7
8继续跟进
9
10
get:function(
url,data,callback,type){
11//shift
argumentsifdataargumentwasomited
12if(
jQuery.isFunction(data)){
13
type=type||callback;
14
callback=data;
15
data=null;
16
}
17
18returnjQuery.ajax({
19
type:"GET",
20
url:url,
21
data:data,
22
success:callback,
23
dataType:type
24
});
25
26
跟进jQuery.ajax,下面是ajax方法的代码片段:
1//BuildtemporaryJSONPfunction
2if(s.dataType==="json"&&(s.data&&jsre.test(s.data)||jsre.test(s.url))
){
3jsonp=s.jsonpCallback||("jsonp"+jsc++);
4
5//Replacethe=?sequencebothinthequerystringandthedata
6if(s.data){
7s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");
8}
9
10s.url=s.url.replace(jsre,"="+jsonp+"$1");
11
12//Weneedtomakesure
13//thataJSONPstyleresponseisexecutedproperly
14s.dataType="script";
15
16//HandleJSONP-styleloading
17window[jsonp]=window[jsonp]||function(
tmp){
18data=tmp;
19success();
20complete();
21//Garbagecollect
22window[jsonp]=undefined;
23
24try{
25deletewindow[jsonp];
26}catch(e){}
27
28if(head){
29head.removeChild(script);
30}
31};
32}
33
34if(s.dataType==="script"&&s.cache===null)
{
35s.cache=false;
36}
37
38if(s.cache===false&&type==="GET")
{
39varts=now();
40
41//tryreplacing_=ifitisthere
42varret=s.url.replace(rts,"$1_="+ts+"$2");
43
44//ifnothingwasreplaced,addtimestamptotheend
45s.url=ret+((ret===s.url)?(rquery.test(s.url)?"&":"?")+"_="+ts
:"");
46}
47
48//Ifdataisavailable,appenddatatourlforgetrequests
49if(s.data&&type==="GET")
{
50s.url+=(rquery.test(s.url)?"&":"?")+s.data;
51}
52
53//Watchforanewsetofrequests
54if(s.global&&!jQuery.active++)
{
55jQuery.event.trigger("ajaxStart");
56}
57
58//MatchesanabsoluteURL,andsavesthedomain
59varparts=rurl.exec(s.url),
60remote=parts&&(parts[1]&&parts[1]!==location.protocol||parts[2]!==location.host);
61
62//Ifwe'rerequestingaremotedocument
63//andtryingtoloadJSONorScriptwithaGET
64if(s.dataType==="script"&&type==="GET"&&remote
){
65varhead=document.getElementsByTagName("head")[0]||document.documentElement;
66varscript=document.createElement("script");
67script.src=s.url;
68if(s.scriptCharset){
69script.charset=s.scriptCharset;
70}
71
72//HandleScriptloading
73if(!jsonp){
74vardone=false;
75
76//Attachhandlersforallbrowsers
77script.onload=script.onreadystatechange=function()
{
78if(!done&&(!this.readyState||
79this.readyState==="loaded"||this.readyState==="complete")
){
80done=true;
81success();
82complete();
83
84//HandlememoryleakinIE
85script.onload=script.onreadystatechange=null;
86if(head&&script.parentNode){
87head.removeChild(script);
88}
89}
90};
91}
92
93//UseinsertBeforeinsteadofappendChildtocircumventanIE6bug.
94//Thisariseswhenabasenodeisused(#2709and#4378).
95head.insertBefore(script,head.firstChild);
96
97//Wehandleeverythingusingthescriptelementinjection
98returnundefined;
99}
100
上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;
这个地方也就是Taven.李锡远所说的“随机变一个方法名”;
关注第14行,这一行相当关键,注定了我们的结果最终是<Script>;然后是构造Script片段,第95行在Head中添加该片段,修成正果;
不仅仅是jQuery,很多js框架都是用了同样的跨域方案,:)说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”
下面开始贴出方法。
//跨域(可跨所有域名)
1 | $.getJSON( " , function (json){ |
2 | //要求远程请求页面的数据格式为: ?(json_data)//例如://?([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}])alert(json[0]._name); |
3 | }); |
因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。
具体getJSON的使用说明,请参考JQUERY手册。
下面一个是跨域执行的真实例子:
1 | <script src= " type= "text/javascript" ></script> |
2 | <script type= "text/javascript" > |
3 | //跨域(可跨所有域名) |
4 | $.getJSON( " , {id:0,action: 'jobcategoryjson' }, function (json) {alert(json[0].pid);alert(json[0].items[0]._name);}); |
5 | </script> |
jQuery跨域原理:
浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;
看下面的例子:
1 | <script type= "text/javascript" src= " > </script> |
2 | 响应值:parseResponse({ "Name" : "Cheeso" , "Rank" : 7}) |
withpadding上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?
貌似并没有<Script>标记的出现!?OKay,翻看源码来看:
页面调用的是getJSON:
1 | getJSON: function ( |
2 | return jQuery.get(url, " ); |
3 | }, |
8继续跟进
9
10
get:function(
url,data,callback,type){
11//shift
argumentsifdataargumentwasomited
12if(
jQuery.isFunction(data)){
13
type=type||callback;
14
callback=data;
15
data=null;
16
}
17
18returnjQuery.ajax({
19
type:"GET",
20
url:url,
21
data:data,
22
success:callback,
23
dataType:type
24
});
25
26
跟进jQuery.ajax,下面是ajax方法的代码片段:
1//BuildtemporaryJSONPfunction
2if(s.dataType==="json"&&(s.data&&jsre.test(s.data)||jsre.test(s.url))
){
3jsonp=s.jsonpCallback||("jsonp"+jsc++);
4
5//Replacethe=?sequencebothinthequerystringandthedata
6if(s.data){
7s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");
8}
9
10s.url=s.url.replace(jsre,"="+jsonp+"$1");
11
12//Weneedtomakesure
13//thataJSONPstyleresponseisexecutedproperly
14s.dataType="script";
15
16//HandleJSONP-styleloading
17window[jsonp]=window[jsonp]||function(
tmp){
18data=tmp;
19success();
20complete();
21//Garbagecollect
22window[jsonp]=undefined;
23
24try{
25deletewindow[jsonp];
26}catch(e){}
27
28if(head){
29head.removeChild(script);
30}
31};
32}
33
34if(s.dataType==="script"&&s.cache===null)
{
35s.cache=false;
36}
37
38if(s.cache===false&&type==="GET")
{
39varts=now();
40
41//tryreplacing_=ifitisthere
42varret=s.url.replace(rts,"$1_="+ts+"$2");
43
44//ifnothingwasreplaced,addtimestamptotheend
45s.url=ret+((ret===s.url)?(rquery.test(s.url)?"&":"?")+"_="+ts
:"");
46}
47
48//Ifdataisavailable,appenddatatourlforgetrequests
49if(s.data&&type==="GET")
{
50s.url+=(rquery.test(s.url)?"&":"?")+s.data;
51}
52
53//Watchforanewsetofrequests
54if(s.global&&!jQuery.active++)
{
55jQuery.event.trigger("ajaxStart");
56}
57
58//MatchesanabsoluteURL,andsavesthedomain
59varparts=rurl.exec(s.url),
60remote=parts&&(parts[1]&&parts[1]!==location.protocol||parts[2]!==location.host);
61
62//Ifwe'rerequestingaremotedocument
63//andtryingtoloadJSONorScriptwithaGET
64if(s.dataType==="script"&&type==="GET"&&remote
){
65varhead=document.getElementsByTagName("head")[0]||document.documentElement;
66varscript=document.createElement("script");
67script.src=s.url;
68if(s.scriptCharset){
69script.charset=s.scriptCharset;
70}
71
72//HandleScriptloading
73if(!jsonp){
74vardone=false;
75
76//Attachhandlersforallbrowsers
77script.onload=script.onreadystatechange=function()
{
78if(!done&&(!this.readyState||
79this.readyState==="loaded"||this.readyState==="complete")
){
80done=true;
81success();
82complete();
83
84//HandlememoryleakinIE
85script.onload=script.onreadystatechange=null;
86if(head&&script.parentNode){
87head.removeChild(script);
88}
89}
90};
91}
92
93//UseinsertBeforeinsteadofappendChildtocircumventanIE6bug.
94//Thisariseswhenabasenodeisused(#2709and#4378).
95head.insertBefore(script,head.firstChild);
96
97//Wehandleeverythingusingthescriptelementinjection
98returnundefined;
99}
100
上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;
这个地方也就是Taven.李锡远所说的“随机变一个方法名”;
关注第14行,这一行相当关键,注定了我们的结果最终是<Script>;然后是构造Script片段,第95行在Head中添加该片段,修成正果;
不仅仅是jQuery,很多js框架都是用了同样的跨域方案,:)说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”
相关文章推荐
- jQuery 跨域访问问题解决方法
- JQuery其中可以跨域访问的AJAX方法
- Jquery 跨域访问 Lightswitch OData Service的方法
- WebWorks中使用JQuery的getJSON方法进行跨域访问
- jquery下利用jsonp跨域访问实现方法
- jQuery 跨域访问问题解决方法
- jQuery 跨域访问问题解决方法
- jquery实现跨域访问的方法
- jquery下利用jsonp跨域访问实现方法
- jquery 跨域访问问题解决方法(笔记)
- 运用jQuery的ajax方法实现跨域访问
- jQuery 跨域访问问题解决方法
- jQuery 跨域访问问题解决方法
- jQuery 跨域访问问题解决方法(转)
- Jquery 跨域访问 Lightswitch OData Service的方法
- jquery 跨域访问问题解决方法(笔记)
- 跨域访问Jquery实现
- SilverLight跨域访问及其常用的几种解决方法
- jquery:利用jsonp跨域访问--转载