JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;
有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?
其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。
今天2013年8月2日又抽时间整理了下,修改了优化在线调用的方法。
其实跨域有两种思路,
下面说下两种方法的实现:
=================思路一:通过js跨域访问=====================
一、服务器端(远程访问段),构造指定的json格式:
1
2
3
4
5
6
7
8
9
|
var
url
=
"http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?"
//返回格式: ?(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}]}]);
因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。
具体getJSON的使用说明,请参考JQUERY手册。
二、客户端实际调用,下面一个是跨域执行的真实例子(可跨所有域名):
1
2
3
4
5
6
7
8
9
10
|
<script
src
=
"http://www.aiisen.com/commons/scripts/jquery.js"
type
=
"text/javascript"
>
</script>
<script
type
=
"text/javascript"
>
$
.
getJSON
(
"http://www.aiisen.com/CsAjax.do?method=getCrossJson&jsoncallback=?"
,
}
)
;
</script>
|
=================思路二:后台写代码访问=====================
第一种思路有一个缺陷:就是如果需要访问的服务端你无法控制的话,那么你也就无计可施了,所以提供第二种思路,后台通过HttpClient 和HttpGet直接访问,
=========================jQuery跨域原理==========================
浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;
看下面的例子:
1
2
|
<script
type
=
"text/javascript"
src
=
"http://domain2.com/getjson?jsonp=parseResponse"
>
</script>
响应值:
parseResponse
(
{
"Name"
:
"Cheeso"
,
"Rank"
:
7
}
)
|
这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?
貌似并没有<Script>标记的出现!?OKay,翻看源码来看:
继续跟进
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
(
@H_404_99@s
.
@H_404_99@dataType
===
" json "
&&
(
@H_404_99@s
.
@H_404_99@data
&&
@H_404_99@jsre
.
test
(
@H_404_99@s
.
@H_404_99@data
)
||
@H_404_99@jsre
.
test
(
@H_404_99@s
.
@H_404_99@url
)
)
)
{
// Replace the =? sequence both in the query string and the data
@H_404_99@s
.
@H_404_99@data
=
(
@H_404_99@s
.
@H_404_99@data
+
""
)
.
replace
(
@H_404_99@jsre
,
" = "
+
@H_404_99@jsonp
+
" $1 "
)
;
}
@H_404_99@s
.
@H_404_99@url
=
@H_404_99@s
.
@H_404_99@url
.
replace
(
@H_404_99@jsre
,
" = "
+
@H_404_99@jsonp
+
" $1 "
)
;
// We need to make sure
// that a JSONP style response is executed properly
// Handle JSONP-style loading
success
(
)
;
complete
(
)
;
// Garbage collect
try
{
if
(
head
)
{
}
}
;
}
}
// try replacing _= if it is there
var
@H_404_99@ret
=
@H_404_99@s
.
@H_404_99@url
.
replace
(
@H_404_99@rts
,
" $1_= "
+
@H_404_99@ts
+
" $2 "
)
;
// if nothing was replaced,add timestamp to the end
@H_404_99@s
.
@H_404_99@url
=
@H_404_99@ret
+
(
(
@H_404_99@ret
===
@H_404_99@s
.
@H_404_99@url
)
?
(
@H_404_99@rquery
.
test
(
@H_404_99@s
.
@H_404_99@url
)
?
" & "
:
" ? "
)
+
" _= "
+
@H_404_99@ts
:
""
)
;
}
// If data is available,append data to url for get requests
@H_404_99@s
.
@H_404_99@url
+=
(
@H_404_99@rquery
.
test
(
@H_404_99@s
.
@H_404_99@url
)
?
" & "
:
" ? "
)
+
@H_404_99@s
.
@H_404_99@data
;
}
// Watch for a new set of requests
}
// Matches an absolute URL,and saves the domain
@H_404_99@remote
=
@H_404_99@parts
&&
(
@H_404_99@parts
[
1
]
&&
@H_404_99@parts
[
1
]
!==
@H_404_99@location
.
@H_404_99@protocol
||
@H_404_99@parts
[
2
]
!==
@H_404_99@location
.
@H_404_99@host
)
;
// If we're requesting a remote document
// and trying to load JSON or Script with a GET
@H_723_3016@
var
@H_404_99@head
=
@H_404_99@document
.
getElementsByTagName
(
" head "
)
[
0
]
||
@H_404_99@document
.
@H_404_99@documentElement
;
}
// Handle Script loading
if
(
!
jsonp
)
{
// Attach handlers for all browsers
@H_404_3230@
@H_404_99@script
.
@H_404_99@onload
=
@H_404_99@script
.
@H_404_99@onreadystatechange
=
function
(
)
{
success
(
)
;
complete
(
)
;
// Handle memory leak in IE
@H_807_3404@
@H_404_99@script
.
@H_404_99@onload
=
@H_404_99@script
.
@H_404_99@onreadystatechange
=
null
;
}
}
}
;
@H_925_3502@
}
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
// We handle everything using the script element injection
}
|
上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;
这个地方也就是Taven.李锡远所说的“随机变一个方法名”;
关注第14行,这一行相当关键,注定了我们的结果最终是<Script>;然后是构造Script片段,第95行在Head中添加该片段,修成正果;
不仅仅是jQuery,很多js框架都是用了同样的跨域方案,:)说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”
ps:http://www.aiisen.com/ajax-cross-domain-access-zh.html
转载注明: http://www.itjhwd.com/ajax-jquery-kuayu/