常用關於 JavaScript 中的跨域存取方法

來源:互聯網
上載者:User

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資料。這樣就想當於在你的頁面裡面執行了以上的代碼。從而實現了跨域傳遞資料。

 

原文:http://www.cnblogs.com/NNUF/archive/2012/08/15/2639793.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.