1. 程式人生 > >JS跨域呼叫之document.domain--相同基礎域名頁面之間的呼叫

JS跨域呼叫之document.domain--相同基礎域名頁面之間的呼叫

最近專案需要跨域呼叫JS,整理一下相關知識,寫幾個帖子記錄一下學習歷程。 

例子只需要1個tomcat即可,這裡我的tomcat埠都改成80了。 

背景:瀏覽器在執行Javascript時,出於對安全性的考慮,禁止兩個或者多個不同域的頁面進行互相操作。 
相同域的頁面在相互操作的時候不會有任何問題。 

如下例子:檔案放置於%TOMCAT_HOME%/webapps/domain/目錄下 
1. parent.html

Html程式碼  收藏程式碼
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  5. <title>parent</title>  
  6. <script>  
  7.     // document.domain = "wwwcomy.com";  
  8.     function parentFunction() {  
  9.         alert('function in parent');  
  10.     }  
  11.     function callChild() {  
  12.         child.window.childFunction();  
  13.         /*  
  14.             child 為iframe的name屬性值,  
  15.             不能為id,因為在FireFox下id不能獲取iframe物件  
  16.         */  
  17.     }  
  18. </script>  
  19. </head>  
  20. <body>  
  21. <input type="button" name="call child"  value="call child"
     onclick="callChild()"/>  
  22. <br/><br/>  
  23. <!--<iframe name="child" src="http://d1.wwwcomy.com/domain/child.html" >-->  
  24. <iframe name="child" src="child.html" >  
  25. </iframe>  
  26. </body>  
  27. </html>  


2.child.html

Html程式碼  收藏程式碼
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  5. <title>child</title>  
  6. <script>  
  7.     // document.domain = "wwwcomy.com";  
  8.     function childFunction() {  
  9.         alert('function in child');  
  10.     }  
  11.     function callParent() {  
  12.         parent.parentFunction();  
  13.     }  
  14. </script>  
  15. </head>  
  16. <body>  
  17. <input type="button" name="call parent" value="call parent" onclick="callParent()"/>  
  18. </body>  
  19. </html>  


通過localhost/domain/parent.html訪問,則可以在子頁面和父頁面之間相互呼叫,點選按鈕即可看到效果。 

接下來我們模擬不用域名的呼叫,初步我們先處理相同基礎域名這個前提下,頁面之間的呼叫,即同頂級域名的不同二級域名之間的呼叫,如: 
d1.wwwcomy.com/domain/parent.html 
與 
d2.wwwcomy.com/domain/child.html 

首先需要修改本地域名對映檔案hosts,XP系統此檔案地址在C:\WINDOWS\system32\drivers\etc\hosts,win7與linux請google 

新增兩個域名對映: 
127.0.0.1 d1.wwwcomy.com 
127.0.0.1 d2.wwwcomy.com 

接下來將parent.html中iframe的src替換為註釋的那一段。 

此時我們在瀏覽器中輸入d2.wwwcomy.com/domain/parent.html即可訪問到對應頁面,這樣就可以模擬 d2.wwwcomy.com 與 d1.wwwcomy.com兩個二級域名頁面之間的呼叫了。 

如果沒有去掉document.domain 這行的註釋,瀏覽器會報錯,chrome中的報錯資訊為 
引用 Unsafe JavaScript attempt to access frame with URL http://d1.wwwcomy.com/domain/child.html from frame with URL http://d2.wwwcomy.com/domain/parent.html. Domains, protocols and ports must match. 

即不安全的JS呼叫。 

接下來取消註釋parent與child頁面中的 document.domain 這行程式碼,發現JS現在可以相互呼叫了。 
注意兩個檔案都需要這行程式碼,如果依舊報錯請檢視是不是由於瀏覽器的快取問題。

下面是對document.domain的使用說明和限制條件: 
域名必須屬於同一個基礎域名!而且所用的協議,埠都要一致,否則無法利用document.domain進行跨域

例子中的基礎域名就是"wwwcomy.com",這個域名不能隨意指定的,也就是說,如果我們把剛才例子中的document.domain設定為"sina.com"是會報引數無效的錯誤的。 

通過這種方法,就可以實現同一個基礎域名下兩個二級域名頁面之間JS的跨域相互呼叫。後面的帖子會介紹其他跨域解決方案。