跨域問題小記以及jsonp簡談

去年,在給導師做項目時需要解決一個跨域問題,當時沒弄過,就從網上找了資料給解決了,時至今日讓我再提怎麼做的,早已忘掉。再有就是以前聽過jsonp,但是對此概念全然不知,只覺得跟json只差一個p。直到前幾天帶我的師傅跟我說了下jsonp,然後又自己查看了jsonp的原理後,才知道jsonp是怎麼一回事。爲了以後自己可以快速拾起這些知識,在這裏粗略記錄一下。


iframe跨域

1.遇到的問題

我們的頁面A.html

別人的頁面B.html(兩個頁面不同域)

A.html要嵌套B.html頁面,而且被嵌套的B.html頁面需要調用A.html的js方法

思想:

在a.html同一個域下創建一個c.html,就是利用c.html這個頁面來作爲b.html頁面訪問a.html頁面js方法的橋樑

通過在a.html中嵌套b.html,然後在嵌套在a中的b.html頁面中再(有點繞,仔細體會)動態創建一個iframe,把c.html頁面嵌套進去,然後b.html便可以通過動態嵌套的c.html頁面來調用a.html的js方法了。

隨便畫了張圖,表示下嵌套的層次:


實現:

直接上代碼比較清楚:(ip跟域名來說不是在同一個域下,所以可以用一臺機子中ip127.0.0.1與localhost來模擬)

localhost:8080/test1/a.html代碼 

<html>
<head>
<title>無標題文檔</title>
</head>

<body>
<iframe src="http://127.0.0.1:8080/test2/b.html"  frameborder="0" scrolling="no" marginheight="0" marginwidth="0" name="myframe"></iframe>
<script>
	function test(data)
	{
	  alert("這個是a中的方法,參數:"+data);
	}
</script>
</body>
</html>
這段代碼中嵌套了b.html頁面,然後,我們的目的是點擊b.html頁面中按鈕可以調用a.html頁面中的test方法。

localhost:8080/test1/c.html代碼  (c.html頁面與a.html頁面在同一個域中,實驗中與a.html頁面同一目錄下了)

<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.onload = function(){
    var text = window.location.href.split('=')[1]
    parent.parent.test(text);
}
</script>
</head>
<body>

</body>
</html>
c.html頁面中沒有什麼代碼,就是爲了b.html頁面調用此頁面的時候,幫助調用a.html中的方法。 

c調用a的方法的時候用了 parent.parent.方法名來調用的,因爲c是作爲a底下兩層嵌套。


127.0.0.1:8080/test2/b.html代碼

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>跨域測試</title>
</head>

<body>
<ul>
<li>測試</li>
</ul>
<input type="button" onclick="exec_iframe()" value="調用a頁面方法"></input>
<script>
	 function exec_iframe(){  //此方法就是動態創建iframe,然後將c.html頁面嵌套進來
	  var text = "abcddddddd";
      if(typeof(exec_obj)=='undefined'){  
        exec_obj = document.createElement('iframe');  
        exec_obj.name = 'tmp_frame';  
        exec_obj.src = 'http://localhost:8080/test1/c.html?content='+text;  
        exec_obj.style.display = 'none';  
        document.body.appendChild(exec_obj);  
    }else{  
        exec_obj.src = 'http://localhost:8080/test1/c.html?content='+text;  
    }  
  } 
</script>
</body>
</html>
當點擊b中的按鈕時,會調用方法exec_iframe() ,然後動態將c頁面嵌套進來,c頁面初始化便會調用其頁面中的js方法,便實現了調用a頁面中的test方法。


----------------------------------------------------------------------------------------------------------------
總結下流程:

啓動tomcat,訪問a.html頁面


       b頁面中的內容便加載進來了,在b.html中有文本以及一個按鈕,然後點擊按鈕,去調用a.html中的方法,這個過程就是上面說的,在b中動態嵌入c頁面,然後由c頁面來調用a中的方法。(參數沒有轉碼,沒什麼影響)



同理,如果想在a中調用b中的方法的話,那可以在b.html同目錄下或者說同域下創建一個頁面d,d中調用b中的方法(parent.window.myframe.方法名,此處的myframe是b在a頁面中的iframe名稱),當a也調用b中方法的時候,同樣在頁面中動態創建一個iframe來嵌套d頁面。


jsonp簡談

  以我自己的理解,jsonp不是什麼協議,更不是什麼數據格式,只是幫助獲取外域數據的一種方法。

  這種方法就是利用了瀏覽器對<script src ="http://.............." ></script>不採取“同源策略”的特點來實現數據獲取的。

  當我們使用src時,是可以調用別的站點的資源,舉例來說:

 a.html頁面中有段js

<script>
 function test()
{ 
    alert("通過遠程資源文件調用我啊");
}
</script>
<script src="http://xxxxx/remote.js"></script>

遠程的這個remote.js文件的內容是:

test();

那當a頁面加載時會彈出彈框。

其實,這就是jsonp的依賴的原理,src指向的不止是一個js文件,同樣可以是一個請求地址:

src="http://xxxx/xxxx/getcount?callback=test"(callback就是一個普通參數名,完全可以換成別的,只要跟後臺約定好就ok了)

這樣的話我們可以在後臺方法getcount中拿到參數callback,這個callback參數是幹嘛的呢,就是向後臺說明你從後臺拿到數據後,要用哪個方法來處理,也就是讓後臺給你返回像上面test()方法這樣的東西。

給個完整例子就是:

<script>
 function dealcount(data)
{ 
    alert("獲取後臺數據:"+data);
 //拿到數據,處理數據
}
</script>
<script src="http://xxxx/xxxx/getcount?callback=dealcount"></script></span>

當這個頁面加載的時候便回去請求這個鏈接,後臺拿到參數test,以及經過後臺處理好的數據data,然後返回來 dealcount(data),那麼這個是不是就跟remote.js中寫個dealcount(data)一樣了,就會執行自己頁面上寫的dealcount(data)方法了。


但是這個例子是個靜態的,不能每次都是頁面加載的時候來請求吧。要需要時再去請求,那就寫個方法去動態生成script標籤,然後動態加載到頁面中吧。

function jsonpRequest(){ 
   var url = "http://xxxx/xxxx/getcount?callback=dealcount";</span>
    //創建script標籤,設置其屬性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    //把script標籤加入head,此時調用開始
    document.getElementsByTagName('head')[0].appendChild(script);
}

jsonp在jquery中也可以使用ajax的方式,只要知道了這個jsonp是個什麼東西,那麼ajax中的使用也就是一看便明瞭 了。


如果有別的跨域以及這方面的知識,可以推薦給我,謝謝!





                                                                                                                                                              --------------------  等回頭看看自己,寫的又傻又笨的時候,那麼說明我成長了!




 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章