www.78ajax,ajax跨域访问 JQuery 的跨域方法

JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;

有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?

其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。

今天2013年8月2日又抽时间整理了下,修改了优化在线调用的方法。

其实跨域有两种思路,

思路一:就是通过js跨域访问;思路二:是通过后台写代码访问

下面说下两种方法的实现:

@H_404_16@=================思路一:通过js跨域访问@H_404_16@=====================

一、服务器端(远程访问段),构造指定的json格式:

JavaScript

var url = "http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?"

$.getJSON(url,{www_url:"www.aiisen.com"},function(json) {

//返回格式: ?(json_data)

/*返回数据: ?([{"www_url":"www.aiisen.com","www_name":"www_name","items":[{"p_name":"安徽省","p_index":340000},{"p_name":"北京市","p_index":110000}]}]) */

//调用实例:alert(json[0].www_url);

});

1

2

3

4

5

6

7

8

9

var

url

=

"http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?"

$

.

getJSON

(

url

,

{

www_url

:

"www.aiisen.com"

}

,

function

(

json

)

{

//返回格式: ?(json_data)

/*返回数据: ?([{"www_url":"www.aiisen.com",

"items":[{"p_name":"安徽省","p_index":110000}]}]) */

//调用实例:alert(json[0].www_url);

}

)

;

注意:CsAjax.do?method=getCrossJson中,在输出JSON数据时,一定要带参数:jsoncallback,并将获取的内容放到返回JSON数据的前面,假设实际获取的值为Jquery123456_7890123,那么返回的值就是 Jquery123456_7890123([{“www_url”:”www.aiisen.com”,”www_name”:”www_name”,”items”:[{“p_name”:”安徽省”,”p_index”:340000},{“p_name”:”北京市”,”p_index”:110000}]}]);

这个贴上我的远程端的获取代码java写的其他语言类似参考:

JavaScript

String www_url = (String) request.getAttribute("www_url");

String jsoncallback = (String) request.getAttribute("jsoncallback");

if (StringUtils.isBlank(www_url)) {

www_url = "www.aiisen.com";

}

JSONObject jsonb = new JSONObject();

jsonb.put("www_url",www_url);

jsonb.put("www_name","爱森家园");

JSONArray items = new JSONArray();

JSONObject item = new JSONObject();

item.put("p_name","安徽省");

item.put("p_index",340000);

items.put(item);

jsonb.put("p_name","北京市");

jsonb.put("p_index",110000);

items.put(item);

jsonb.put("items",items);

String json = jsoncallback + "([" + jsonb.toString() + "])";

if (StringUtils.isNotBlank(jsoncallback)) {

//将特殊构造的数据:json 返回到页面

} else {

//将正常的数据jsonb返回到页面

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

String

www_url

=

(

String

)

request

.

getAttribute

(

"www_url"

)

;

String

jsoncallback

=

(

String

)

request

.

getAttribute

(

"jsoncallback"

)

;

if

(

StringUtils

.

isBlank

(

www_url

)

)

{

www_url

=

"www.aiisen.com"

;

}

JSONObject

jsonb

=

new

JSONObject

(

)

;

jsonb

.

put

(

"www_url"

,

www_url

)

;

jsonb

.

put

(

"www_name"

,

"爱森家园"

)

;

JSONArray

items

=

new

JSONArray

(

)

;

JSONObject

item

=

new

JSONObject

(

)

;

item

.

put

(

"p_name"

,

"安徽省"

)

;

item

.

put

(

"p_index"

,

340000

)

;

items

.

put

(

item

)

;

jsonb

.

put

(

"p_name"

,

"北京市"

)

;

jsonb

.

put

(

"p_index"

,

110000

)

;

items

.

put

(

item

)

;

jsonb

.

put

(

"items"

,

items

)

;

String

json

=

jsoncallback

+

"(["

+

jsonb

.

toString

(

)

+

"])"

;

if

(

StringUtils

.

isNotBlank

(

jsoncallback

)

)

{

//将特殊构造的数据:json 返回到页面

}

else

{

//将正常的数据jsonb返回到页面

}

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

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

二、客户端实际调用,下面一个是跨域执行的真实例子(可跨所有域名):

JavaScript

$.getJSON("http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?",function(json) {

alert(json[0].www_url);

alert(json[0].www_name);

alert(json[0].items[0].p_name);

});

1

2

3

4

5

6

7

8

9

10

=

"http://www.aiisen.com/commons/scripts/jquery.js"

type

=

"text/javascript"

>

=

"text/javascript"

>

$

.

getJSON

(

"http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?"

,

{

www_url

:

"www.aiisen.com"

}

,

function

(

json

)

{

alert

(

json

[

0

]

.

www_url

)

;

alert

(

json

[

0

]

.

www_name

)

;

alert

(

json

[

0

]

.

items

[

0

]

.

p_name

)

;

}

)

;

@H_404_16@=================思路二:后台写代码访问@H_404_16@=====================

第一种思路有一个缺陷:就是如果需要访问的服务端你无法控制的话,那么你也就无计可施了,所以提供第二种思路,后台通过HttpClient 和HttpGet直接访问,

然后在后台获取访问的数据,在做处理,返回到页面即可。

这个可以参考我的文章:有道翻译 使用

=========================jQuery跨域原理==========================

浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的

看下面的例子:

JavaScript

响应值:parseResponse({"Name": "Cheeso","Rank": 7})

1

2

=

"text/javascript"

src

=

"http://domain2.com/getjson?jsonp=parseResponse"

>

响应值:

parseResponse

(

{

"Name"

:

"Cheeso"

,

"Rank"

:

7

}

)

这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?

貌似并没有

页面调用的是getJSON:

JavaScript

getJSON: function ( url,data,callback ) {

return jQuery.get(url,callback," json " );

},

1

2

3

getJSON

:

function

(

url

,

data

,

callback

)

{

return

jQuery

.

get

(

url

,

callback

,

" json "

)

;

}

,

继续跟进

JavaScript

get: function ( url,type ) {

// shift arguments if data argument was omited

if ( jQuery.isFunction( data ) ) {

type = type || callback;

callback = data;

data = null ;

}

return jQuery.ajax({

type: " GET ",url: url,data: data,success: callback,dataType: type

});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

get

:

function

(

url

,

type

)

{

// shift arguments if data argument was omited

if

(

jQuery

.

isFunction

(

data

)

)

{

type

=

type

||

callback

;

callback

=

data

;

data

=

null

;

}

@H_214_1404@

return

jQuery

.

ajax

(

{

type

:

" GET "

,

url

:

url

,

data

:

data

,

success

:

callback

,

dataType

:

type

}

)

;

跟进jQuery.ajax,下面是ajax方法的代码片段:

Java

// Build temporary JSONP function

if ( s.dataType === " json " && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {

jsonp = s.jsonpCallback || ( " jsonp " + jsc ++ );

// Replace the =? sequence both in the query string and the data

if ( s.data ) {

s.data = (s.data + "" ).replace(jsre," = " + jsonp + " $1 " );

}

s.url = s.url.replace(jsre," = " + jsonp + " $1 " );

// We need to make sure

// that a JSONP style response is executed properly

s.dataType = " script " ;

// Handle JSONP-style loading

window[ jsonp ] = window[ jsonp ] || function ( tmp ) {

data = tmp;

success();

complete();

// Garbage collect

window[ jsonp ] = undefined;

try {

delete window[ jsonp ];

} catch (e) {}

if ( head ) {

head.removeChild( script );

}

};

}

if ( s.dataType === " script " && s.cache === null ) {

s.cache = false ;

}

if ( s.cache === false && type === " GET " ) {

var ts = now();

// try replacing _= if it is there

var ret = s.url.replace(rts," $1_= " + ts + " $2 " );

// if nothing was replaced,add timestamp to the end

s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? " & " : " ? " ) + " _= " + ts : "" );

}

// If data is available,append data to url for get requests

if ( s.data && type === " GET " ) {

s.url += (rquery.test(s.url) ? " & " : " ? " ) + s.data;

}

// Watch for a new set of requests

if ( s.global && ! jQuery.active ++ ) {

jQuery.event.trigger( " ajaxStart " );

}

// Matches an absolute URL,and saves the domain

var parts = rurl.exec( s.url ),remote = parts && (parts[ 1 ] && parts[ 1 ] !== location.protocol || parts[ 2 ] !==location.host);

// If we're requesting a remote document

// and trying to load JSON or Script with a GET

if ( s.dataType === " script " && type === " GET " && remote ) {

var head = document.getElementsByTagName( " head " )[ 0 ] || document.documentElement;

var script = document.createElement( " script " );

script.src = s.url;

if ( s.scriptCharset ) {

script.charset = s.scriptCharset;

}

// Handle Script loading

if ( ! jsonp ) {

var done = false ;

// Attach handlers for all browsers

script.onload = script.onreadystatechange = function () {

if ( ! done && ( ! this .readyState ||

this .readyState === " loaded " || this .readyState === " complete " ) ) {

done = true ;

success();

complete();

// Handle memory leak in IE

script.onload = script.onreadystatechange = null ;

if ( head && script.parentNode ) {

head.removeChild( script );

}

}

};

}

// Use insertBefore instead of appendChild to circumvent an IE6 bug.

// This arises when a base node is used (#2709 and #4378).

head.insertBefore( script,head.firstChild );

// We handle everything using the script element injection

return undefined;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

// Build temporary JSONP function

if

(

s

.

dataType

===

" json "

&&

(

s

.

data

&&

jsre

.

test

(

s

.

data

)

||

jsre

.

test

(

s

.

url

)

)

)

{

jsonp

=

s

.

jsonpCallback

||

(

" jsonp "

+

jsc

++

)

;

// Replace the =? sequence both in the query string and the data

if

(

s

.

data

)

{

s

.

data

=

(

s

.

data

+

""

)

.

replace

(

jsre

,

" = "

+

jsonp

+

" $1 "

)

;

}

s

.

url

=

s

.

url

.

replace

(

jsre

,

" = "

+

jsonp

+

" $1 "

)

;

@H_404_2024@

// We need to make sure

// that a JSONP style response is executed properly

s

.

dataType

=

" script "

;

// Handle JSONP-style loading

window

[

jsonp

]

=

window

[

jsonp

]

||

function

(

tmp

)

{

data

=

tmp

;

success

(

)

;

complete

(

)

;

// Garbage collect

window

[

jsonp

]

=

undefined

;

try

{

delete

window

[

jsonp

]

;

}

catch

(

e

)

{

}

if

(

head

)

{

head

.

removeChild

(

script

)

;

}

}

;

}

if

(

s

.

dataType

===

" script "

&&

s

.

cache

===

null

)

{

s

.

cache

=

false

;

}

if

(

s

.

cache

===

false

&&

type

===

" GET "

)

{

var

ts

=

now

(

)

;

// try replacing _= if it is there

var

ret

=

s

.

url

.

replace

(

rts

,

" $1_= "

+

ts

+

" $2 "

)

;

// if nothing was replaced,add timestamp to the end

s

.

url

=

ret

+

(

(

ret

===

s

.

url

)

?

(

rquery

.

test

(

s

.

url

)

?

" & "

:

" ? "

)

+

" _= "

+

ts

:

""

)

;

}

// If data is available,append data to url for get requests

if

(

s

.

data

&&

type

===

" GET "

)

{

s

.

url

+=

(

rquery

.

test

(

s

.

url

)

?

" & "

:

" ? "

)

+

s

.

data

;

}

// Watch for a new set of requests

if

(

s

.

global

&&

!

jQuery

.

active

++

)

{

jQuery

.

event

.

trigger

(

" ajaxStart "

)

;

}

// Matches an absolute URL,and saves the domain

var

parts

=

rurl

.

exec

(

s

.

url

)

,

remote

=

parts

&&

(

parts

[

1

]

&&

parts

[

1

]

!==

location

.

protocol

||

parts

[

2

]

!==

location

.

host

)

;

// If we're requesting a remote document

// and trying to load JSON or Script with a GET

if

(

s

.

dataType

===

" script "

&&

type

===

" GET "

&&

remote

)

{

@H_814_3016@

var

head

=

document

.

getElementsByTagName

(

" head "

)

[

0

]

||

document

.

documentElement

;

var

script

=

document

.

createElement

(

" script "

)

;

script

.

src

=

s

.

url

;

if

(

s

.

scriptCharset

)

{

script

.

charset

=

s

.

scriptCharset

;

}

// Handle Script loading

if

(

!

jsonp

)

{

var

done

=

false

;

// Attach handlers for all browsers

script

.

onload

=

script

.

onreadystatechange

=

function

(

)

{

if

(

!

done

&&

(

!

this

.

readyState

||

this

.

readyState

===

" loaded "

||

this

.

readyState

===

" complete "

)

)

{

done

=

true

;

success

(

)

;

complete

(

)

;

// Handle memory leak in IE

@H_905_3404@

script

.

onload

=

script

.

onreadystatechange

=

null

;

if

(

head

&&

script

.

parentNode

)

{

head

.

removeChild

(

script

)

;

}

}

}

;

@H_957_3502@

}

// Use insertBefore instead of appendChild to circumvent an IE6 bug.

// This arises when a base node is used (#2709 and #4378).

head

.

insertBefore

(

script

,

head

.

firstChild

)

;

// We handle everything using the script element injection

return

undefined

;

}

上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;

这个地方也就是Taven.李锡远所说的“随机变一个方法名”;

关注第14行,这一行相当关键,注定了我们的结果最终是

不仅仅是jQuery,很多js框架都是用了同样的跨域方案,:)说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”

转载注明: http://www.itjhwd.com/ajax-jquery-kuayu/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值