常用關於 JavaScript 中的跨域訪問方法


JS中的跨域是受到限制的,但是跨域有時候又是必須的,藉此,各種高手牛人想盡辦法使得JS能夠跨域獲取數據,有的方法真的很巧妙

在此記錄一下常用的三種跨域方法,如下:

 

一、不同子域名之間的(a.example.com|b.example.com)的跨域訪問。

  這種跨域調用比較常見,比如a.example.com 下的 a.htm 頁面,需要調用 b.example.com 下的 b.htm頁面里面的getData函數, 首先需要在a.htm頁面中用iframe 框架把b.htm頁面引用進來 

<iframe id="b" src="http://b.example.com/b.htm" frameborder="on"></iframe>

然后同時在a.htm頁面與b.htm頁面中設置:document.domain = "example.com"; 這樣a.htm就可以獲取b.htm中的window  documet 然后來獲取b.htm中的數據getData了,獲取b.htm中的document方法為:

function getIframeDocument(id){
    returen document.getElementById(id).contentDocument || document.getElementById(id).document;
}

 

二、不同域名之間的hash傳遞參數(www.a.com | www.b.com)

  常見的一個例子就是iframe自動適應大小,a域名下的a.htm   框架(iframe)了b域名中的b.htm,而b.htm的大小是不固定的,這時候就需要通過跨域傳遞b.htm的寬度與高度到a.htm中。

  這個參數是怎么傳遞的呢?是通過hash來傳遞的(www.b.com/b.htm#width|height)其中#號后面的參數width|height 即為window.location.hash的值

而改變hash的值也不會造成頁面的跳轉,但是這樣還是跨域的,所以需要在a域下增加一個c.htm中間頁面,這樣c.htm與a.htm之間就是相同的域下,可以傳遞數

據,把c.htm頁面通過iframe到b.htm中,由b.htm控制,看下圖:  現在的關系為,a.htm中iframe加入了b.htm,b.htm頁面中iframe加入了c.htm

 

  a.htm代碼如下:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Demo</title>
</head>
<body>
<div id="show">這是A域a</div>
<iframe id="b_iframe" src="http://www.b.com/b.htm" frameborder="on" border="1px" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes" ></iframe>
</body>
</html>

   b.htm代碼如下:

<iframe id="c_iframe"  height="0" width="0"  src="http://www.a.com/c.htm" style="display:none" ></iframe>
<script type="text/javascript">
        var b_width = Math.max(document.documentElement.clientWidth,document.body.clientWidth);
        var b_height = Math.max(document.documentElement.clientHeight,document.body.clientHeight);
        console.log(b_width);
        var c_iframe = document.getElementById("c_iframe");
        console.log(c_iframe.src);
        c_iframe.src = c_iframe.src + "#" + b_width + "|" + b_height; // 這里通過hash傳遞b.htm的寬高 /* http://www.b.com/c.html#width|height */

</script>

 c.htm代碼如下:

<script type="text/javascript">
        var b_iframe = parent.parent.document.getElementById("b_iframe");//a與c是同域,可以通過parent獲取到a.htm中的包含b.htm的框架的dom var hash_url = window.location.hash; //這里可以獲取b.htm中傳遞過來的width|height  var hash_width = hash_url.split("#")[1].split("|")[0]+"px"; //分別獲取值 var hash_height = hash_url.split("#")[1].split("|")[1]+"px";
        console.log("hash_width=" + hash_width);
        console.log("hash_height=" + hash_height);

        b_iframe.style.width = hash_width; //a與c頁面是同域,可以設置樣式
        b_iframe.style.height = hash_height;</script>

這樣就可以通過hash來傳遞數據,缺點是只支持string類型,大小受到限制!

 

三、通過jsonp來實現不通域名之間跨域傳遞數據。

      什么是jsonp(JSONP即JSON with Padding。由於同源策略的限制,XmlHttpRequest只允許請求當前源(域名、協議、端口)的資源。如果要進行跨域請求,我們可以通過使用 html的script標記來進行跨域請求,並在響應中返回要執行的script代碼,其中可以直接使用JSON傳遞javascript對象。這種跨域的通訊方式稱為JSONP。)

  通俗來講就是通過<script type="text/javascript" src="調用生成JS文件的地址並傳遞回調參數"></script> 來調用要執行的代碼。

  也可以通過createElement('script')來生成,如下:  

var JSONP = document.createElement("script") ;//然后設置其src屬性

  因為JS文件無論在什么地方都可以調用並執行,比如各種統計JS等,回調參數是怎么回事呢,就是告訴要傳遞數據的頁面給把數據通過這個函數傳遞給我,大家

大家可以試一下下面這個地址:

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?

上面的地址是flicker的API,其中的jsoncallback=? 中的問號替換成你自定義的回調函數,然后對方就會通過這個回調函數給你傳遞數據:

比如隨便起名一個回調函數vvgcallback:

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=vvgcallback

然后對方生成的js就是這樣的(可以把以上地址復制到地址欄測試):

vvgcallback({
        "title": "Recent Uploads tagged cat",
        "link": "http://www.flickr.com/photos/tags/cat/",
        "description": "",
        "modified": "2012-08-15T06:07:40Z",
        "generator": "http://www.flickr.com/",
        "items": [
       {
            "title": "A squirell about to jump",
            "link": "http://www.flickr.com/photos/64477042@N00/7786494040/",
            "media": {"m":"http://farm9.staticflickr.com/8422/7786494040_a7a506dfdc_m.jpg"},
            "date_taken": "2012-08-10T15:19:40-08:00",
            "description": " <p><a href=\"http://www.flickr.com/people/64477042@N00/\">Dr arun kapoor<\/a> posted a photo:<\/p> <p><a href=\"http://www.flickr.com/photos/64477042@N00/7786494040/\" title=\"A squirell about to jump\"><img src=\"http://farm9.staticflickr.com/8422/7786494040_a7a506dfdc_m.jpg\" width=\"240\" height=\"191\" alt=\"A squirell about to jump\" /><\/a><\/p> <p><\/p>",
            "published": "2012-08-15T06:07:40Z",
            "author": "nobody@flickr.com (Dr arun kapoor)",
            "author_id": "64477042@N00",
            "tags": "barcelona china california birthday christmas city family flowers blue autumn friends england blackandwhite bw food dog baby india house holiday chicago canada black france flower color berlin green bird art fall film beach halloween church girl car fashion birds animals bike festival architecture clouds cat canon germany garden de geotagged fun graffiti hawaii dance football concert asia europe day florida band australia iphone instagramapp"
       },
       {
            "title": "catkeywest",
            "link": "http://www.flickr.com/photos/marshawheatley/7786461540/",
            "media": {"m":"http://farm8.staticflickr.com/7120/7786461540_5e3e28bd3a_m.jpg"},
            "date_taken": "2012-08-14T22:57:21-08:00",
            "description": " <p><a href=\"http://www.flickr.com/people/marshawheatley/\">MarshaWheatley<\/a> posted a photo:<\/p> <p><a href=\"http://www.flickr.com/photos/marshawheatley/7786461540/\" title=\"catkeywest\"><img src=\"http://farm8.staticflickr.com/7120/7786461540_5e3e28bd3a_m.jpg\" width=\"240\" height=\"180\" alt=\"catkeywest\" /><\/a><\/p> ",
            "published": "2012-08-15T06:08:53Z",
            "author": "nobody@flickr.com (MarshaWheatley)",
            "author_id": "85010317@N04",
            "tags": "old cat town florida keywest"
       }]
})

就相當與在頁面執行vvgcallback()函數,括號中間的就是傳遞的JSON數據。這樣就想當於在你的頁面里面執行了以上的代碼。從而實現了跨域傳遞數據。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM