跨域請求,顧名思義,就是一個站點中的資源去訪問另外一個不同域名站點上的資源。但在腳本中進行跨域請求是受安全性限制的。
跨域腳本調用有很多種方法,這里介紹的利用hash來進行iframe結構的跨域訪問。
主要針對此種情況:
站點A:www.aaa.com
站點B:www.bbb.com
其中A為父頁面,B是子頁面,以iframe形式嵌入到A中。
要點:
① <script>中的src屬性是可以跨域的。
② window.location.hash其實就是url中以#開始和分割的錨值參數,改變了hash的值,頁面不會自動刷新,所以一個網頁的狀態得以保存。在父頁面中(子頁面傳值給父頁面同理)通過JS將需要傳遞的值作為字符串來改變子頁面的hash值,子頁面通過定時刷新來察覺自身hash值的變化,從而獲取到父頁面傳遞過來的值。
缺點:
① 雖然改變了hash值不會導致頁面自動刷新,但是url值已經改變,所以使用前進、后退等操作均會造成頁面混亂。
② 只能傳遞字符串類型值。
頁面A: http://domain1/TestCross.html:
1 <html>
2 <head>
3 <script language="javascript" type="text/javascript">
4 var url = "http://domain2/TestCross.html";
5 var oldHash = null;
6 var timer = null;
7 function getHash()
8 {
9 var hash = window.location.hash;
10 if ((hash.length >= 1) && (hash.charAt(0) == '#'))
11 {
12 hash = hash.substring(1);
13 }
14 return hash;
15 }
16 function sendRequest()
17 {
18 var d = document;
19 var t = d.getElementById('request');
20 var f = d.getElementById('alienFrame');
21 f.src = url + "#" + t.value + "<br/>" + new Date();
22 }
23 function setDivHtml(v)
24 {
25 var d = document;
26 var dv = d.getElementById('response');
27 dv.innerHTML = v;
28 }
29 function idle()
30 {
31 var newHash = getHash();
32 if (newHash != oldHash)
33 {
34 setDivHtml(newHash);
35 oldHash = newHash;
36 }
37 timer = window.setTimeout(idle, 100);
38 }
39 function window.onload()
40 {
41 timer = window.setTimeout(idle, 100);
42 }
43 </script>
44 </head>
45 <body>
46 請求:<input type="text" id="request"> <input type="button" value="發送" onclick="sendRequest()" /><br/>
47 回復:<div id="response"></div>
48 <iframe id="alienFrame" src="http://domain2/TestCross.html"></iframe>
49 </body>
50 </html>
頁面B:http://domain2/TestCross.html:
1 <html>
2 <head>
3 <script language="javascript" type="text/javascript">
4 var url = "http://domain1/TestCross.html";
5 var oldHash = null;
6 var timer = null;
7 function getHash()
8 {
9 var hash = window.location.hash;
10 if ((hash.length >= 1) && (hash.charAt(0) == '#'))
11 {
12 hash = hash.substring(1);
13 }
14 return hash;
15 }
16 function sendRequest()
17 {
18 var d = document;
19 var t = d.getElementById('request');
20 var f = parent;
21 //alert(f.document); //試着去掉這個注釋,你會得到“Access is denied”
22 f.location.href = url + "#" + t.value + "<br/>" + new Date();
23 }
24 function setDivHtml(v)
25 {
26 var d = document;
27 var dv = d.getElementById('response');
28 dv.innerHTML = v;
29 }
30 function idle()
31 {
32 var newHash = getHash();
33 if (newHash != oldHash)
34 {
35 setDivHtml(newHash);
36 oldHash = newHash;
37 }
38 timer = window.setTimeout(idle, 100);
39 }
40 function window.onload()
41 {
42 timer = window.setTimeout(idle, 100);
43 }
44 </script>
45 </head>
46 <body>
47 請求:<input type="text" id="request"> <input type="button" value="發送" onclick="sendRequest()" /><br/>
48 回復:<div id="response"></div>
49 </body>
50 </html>
兩個網頁基本相同,第一個網頁內嵌一個iframe,在點擊“發送”按鈕后,會將文本框里的內容通過hash fragment傳給IFRAME。點擊IFRAME里的“發送”按鈕后,它會將文本框里的內容通過hash fragment傳給父窗口。因為是只改動了hash fragment,瀏覽器不會重新load網頁內容,這里使用了一個計時器來檢測URL變化,如果變化了,就更新其中一個div的內容 。