您的位置:首页 > Web前端 > JQuery

ajax跨域访问 JQuery 的跨域方法

2012-10-23 13:07 197 查看
JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。

下面开始贴出方法。

//跨域(可跨所有域名)

1
$.getJSON(
"http://user.hnce.com.cn/getregion.aspx?id=0&jsoncallback=?"
,
function
(json){
2
//要求远程请求页面的数据格式为:
?(json_data)//例如://?([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}])alert(json[0]._name);
3
});
注意,getregion.aspx中,在输出JSON数据时,一定要用Request.QueryString["jsoncallback"],将获取的内容放到返回JSON数据的前面,假设实际获取的值为42342348,那么返回的值就是42342348([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}])

因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。

具体getJSON的使用说明,请参考JQUERY手册。

下面一个是跨域执行的真实例子:

1
<script
src=
"http://common.cnblogs.com/script/jquery.js"
type=
"text/javascript"
></script>
2
<script
type=
"text/javascript"
>
3
//跨域(可跨所有域名)
4
$.getJSON(
"http://e.hnce.com.cn/tools/ajax.aspx?jsoncallback=?"
,
{id:0,action:
'jobcategoryjson'
},
function
(json)
{alert(json[0].pid);alert(json[0].items[0]._name);}); 
5
</script>
转载自csdn:http://blog.csdn.net/misswuyang/archive/2009/10/23/4718737.aspx

jQuery跨域原理:

浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;

看下面的例子:

1
<script
type=
"text/javascript"
src=
"http://domain2.com/getjson?jsonp=parseResponse"
>
</script>
2
响应值:parseResponse({
"Name"
:
"Cheeso"
,
"Rank"
:
7})
这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON
withpadding上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?

貌似并没有<Script>标记的出现!?OKay,翻看源码来看:

页面调用的是getJSON:

1
getJSON:
function
(
url,data,callback){
2
return
jQuery.get(url,
data,callback,
"
json"
);
3
},
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跨域的原理,赵本山说了“情况呢就是这么个情况”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息