首頁 web前端 js教程 js中跨域方法原理詳解_javascript技巧

js中跨域方法原理詳解_javascript技巧

May 16, 2016 pm 03:49 PM
js 跨域

框架中(iframe)的資料。只要協定、網域、連接埠有任何一個不同,都被當作是不同的網域。

下表給出了相對http://store.company.com/dir/page.html同源檢測的結果:

要解決跨域的問題,我們可以使用以下幾種方法:

一、透過jsonp跨域

在js中,我們直接用XMLHttpRequest請求不同域上的資料時,是不行的。但是,在頁面上引入不同網域上的js腳本檔案卻是可以的,jsonp正是利用這個特性來實現的。

例如,有個a.html頁面,它裡面的程式碼需要利用ajax取得一個不同網域上的json數據,假設這個json資料位址是http://example.com/data.php,那麼a.html中的程式碼就可以這樣:

我們看到取得資料的位址後面還有一個callback參數,照慣例是用這個參數名,但是你用其他的也一樣。當然如果取得資料的jsonp位址頁面不是你自己能控制的,就得按照提供資料的那一方的規定格式來操作了。

因為是當做一個js檔案來引入的,所以http://example.com/data.php回傳的必須是一個能執行的js文件,所以這個頁面的php程式碼可能是這樣的:

最終那個頁面輸出的結果是:

所以透過http://example.com/data.php?callback=dosomething得到的js文件,就是我們之前定義的dosomething函數,並且它的參數就是我們需要的json數據,這樣我們就跨域獲得了我們需要的數據。

這樣jsonp的原理就很清楚了,透過script標籤引入一個js文件,這個js文件載入成功後會執行我們在url參數中指定的函數,並且會把我們需要的json資料作為參數傳入。所以jsonp是需要伺服器端的頁面進行對應的配合的。

知道jsonp跨域的原理後我們就可以用js動態產生script標籤來進行跨域操作了,而不用特意的手動的書寫那些script標籤。如果你的頁面使用jquery,那麼透過它封裝的方法就能很方便的來進行jsonp操作了。

原 理是一樣的,只不過我們不需要手動的插入script標籤以及定義回掉函數。 jquery會自動產生一個全域函數來取代callback=?中的問號,之 後取得到資料後又會自動銷毀,其實就是起一個臨時代理函數的作用。 $.getJSON方法會自動判斷是否跨域,不跨域的話,就呼叫普通的ajax方法; 跨域的話,則會以非同步載入js檔案的形式來呼叫jsonp的回呼函數。

2、透過修改document.domain來跨子域

瀏覽器都有一個同源策略,其限制之一就是第一種方法中我們說的不能透過ajax的方法去請求不同來源中的文件。 它的第二個限制是瀏覽器中不同域的框架之間是不能進行js的交互操作的。有一點需要說明,不同的框架之間(父子或同輩),是能夠獲取到彼此的window 對象的,但蛋疼的是你卻不能使用獲取到的window對象的屬性和方法(html5中的postMessage方法是一個例外,還有些瀏覽器例如ie6也可以使用top、parent等少數幾個屬性),總之,你可以當做是只能獲取到一個幾乎無用的window對象。例如,有一個頁面,它的位址是http://www.example.com/a.html , 在這個頁裡面有一個iframe,它的src是http://example .com/b.html, 很顯然,這個頁面與它裡面的iframe框架是不同域的,所以我們是無法通過在頁面中書寫js代碼來獲取iframe中的東西的:

這時候,document.domain就可以派上用場了,我們只要把http://www.example.com/a.htmlhttp://example.com/ b.html這兩個頁面的document.domain都設成相同的網域就可以了。但要注意的是,document.domain的設定是有限制的,我們只能把 document.domain設定成自身或更高一級的父域,而主域必須相同。例如:a.b.example.com 中某文檔的document.domain 可以設成a.b.example.com、b.example.com 、example.com中的任一個,但是不可以設成c.a.b.example.com,因為這是當前域的子域,也不可以設成baidu.com,因為主域已經不相同了。

在頁面 http://www.example.com/a.html 設定document.domain:

在頁面http://example.com/b.html 中也設定document.domain,而且這也是必須的,雖然這個文件的domain就是example.com,但是還是必須顯示的設定document.domain的值:

這樣我們就可以透過js存取到iframe中的各種屬性和物件了。

不過如果你想在http://www.example.com/a.html 頁面中透過ajax直接要求http://example.com/b.html頁面,即使你設定了相同的document.domain還是不行的,所以修改document.domain的方法只適用於不同子網域的框架間的互動。 如果你想透過ajax的方法去與不同子網域的頁面交互,除了使用jsonp的方法外,還可以用一個隱藏的iframe來做一個代理。原理就是讓這個iframe載入一個與你想要透過ajax取得資料的目標頁面處在相同的網域的頁面,所以這個iframe中的頁面是可以正常使用ajax去取得你要的資料的,然後就是透過我們剛剛講得修改document.domain的方法,讓我們能透過js完全控制這個iframe,這樣我們就可以讓iframe去發送ajax請求,然後收到的資料我們也可以獲得了。

3、使用window.name來進行跨域

window 物件有name屬性,該屬性有個特徵:即在一個視窗(window)的生命週期內,視窗載入的所有的頁面都是共享一個window.name的,每個頁面對window. name都有讀寫的權限,window.name是持久存在一個視窗載入過的所有頁面中的,並不會因為新頁面的載入而重置。

例如:有一個頁a.html,它裡面有這樣的程式碼:

再看b.html頁面的程式碼:

a.html頁面載入後3秒,跳到了b.html頁面,結果為:

我 看到在b.html頁面上成功取得到了它的上一個頁面a.html給window.name設定的值。如果在之後所有載入的頁面都沒對 window.name進行修改的話,那麼所有這些頁面取得到的window.name的值都是a.html頁面設定的那個值。當然,如果有需要,其中的 任何一個頁面都可以對window.name的值進行修改。注意,window.name的值只能是字串的形式,這個字串的大小最大能允許2M左右甚 至更大的一個容量,具體取決於不同的瀏覽器,但一般是夠用了。

上面的例子中,我們用到的頁面a.html和b.html是處於同一個域的,但是即使a.html與b.html處於不同的域中,上述結論同樣是適用的,這也正是利用window.name進行跨域的原理。

下面就來看看具體是怎麼樣透過window.name來跨域取得資料的。還是舉例說明。

例如有一個www.example.com/a.html頁面,需要透過a.html頁面裡的js來取得另一個位於不同網域上的頁面www.cnblogs.com /data.html裡的數據。

data.html頁面裡的程式碼很簡單,就是給目前的window.name設定一個a.html頁面想要得到的資料值。 data.html裡的程式碼:

那 麼在a.html頁面中,我們要怎麼把data.html頁面載入進來呢?顯然我們不能直接在a.html頁面中透過改變window.location來 載入data.html頁面,因為我們想要即使a.html頁面不跳轉也能得到data.html裡的資料。答案就是在a.html頁面中使用一個隱藏的 iframe來充當一個中間人角色,由iframe去獲取data.html的數據,然後a.html再去得到iframe獲取到的數據。

充當中間人的iframe想要取得到data.html的透過window.name設定的數據,只需要把這個iframe的src設為www.cnblogs.com/data.html就 行了。然後a.html想要得到iframe所取得的數據,也就是想要得到iframe的window.name的值,還必須把這個iframe的src設為跟a.html頁面同一個域才行,不然根據前面講的同源策略,a.html是不能存取到iframe裡的window.name屬性的。這就是 整個跨域過程。

看下a.html頁面的程式碼:

上面的程式碼只是最簡單的原理演示程式碼,你可以對使用js封裝上面的過程,例如動態的創建iframe,動態的註冊各種事件等等,當然為了安全,獲取完數據後,還可以銷毀作為代理的iframe。網路上也有很多類似的現成程式碼,有興趣的可以去找一下。

透過window.name來進行跨域,就是這樣子的。

4、使用HTML5中新引進的window.postMessage方法來跨域傳送資料

window.postMessage(message,targetOrigin) 方法是html5新引進的特性,可以使用它來向其它的window物件發送訊息,無論這個window物件是屬於同源或不同來源,目前IE8 、 FireFox、Chrome、 Opera等瀏覽器都已經支援window.postMessage方法。

呼叫postMessage 方法的window對像是指要接收訊息的那一個window對象,該方法的第一個參數message為要傳送的訊息,型別只能為字串;第二個參數targetOrigin用來限定接收訊息的那個window物件所在的域,如果不想限定域,可以使用通配符* 。

需要接收訊息的window對象,可是透過監聽自身的message事件來取得傳過來的訊息,訊息內容儲存在該事件對象的data屬性中。

上 面所說的向其他window物件發送訊息,其實就是指一個頁面有幾個框架的那種情況,因為每個框架都有一個window物件。在討論第二種方法的時候, 我們說過,不同域的框架間是可以取得到對方的window物件的,而且也可以使用window.postMessage這個方法。下面看一個簡單的範例, 有兩個頁面

我們運行a頁面後得到的結果:

我們看到b頁面成功的收到了訊息。

使用postMessage來跨域傳送資料還是比較直覺和方便的,但是缺點是IE6、IE7不支持,所以用不用還得根據實際需要來決定。

結語:

除了以上幾種方法外,還有flash、在伺服器上設定代理頁面等跨域方式,這裡就不做介紹了。

以上四種方法,可以根據專案的實際情況來進行選擇應用,個人認為window.name的方法既不複雜,也能相容到幾乎所有瀏覽器,這真是極好的一種跨域方法。

以上所述就是本文的全部內容了,希望大家能夠喜歡。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用JS和百度地圖實現地圖平移功能 如何使用JS和百度地圖實現地圖平移功能 Nov 21, 2023 am 10:00 AM

如何使用JS和百度地圖實現地圖平移功能百度地圖是一款廣泛使用的地圖服務平台,在Web開發中經常用於展示地理資訊、定位等功能。本文將介紹如何使用JS和百度地圖API實作地圖平移功能,並提供具體的程式碼範例。一、準備工作使用百度地圖API前,首先需要在百度地圖開放平台(http://lbsyun.baidu.com/)上申請一個開發者帳號,並建立一個應用程式。創建完成

建議:優秀JS開源人臉偵測辨識項目 建議:優秀JS開源人臉偵測辨識項目 Apr 03, 2024 am 11:55 AM

人臉偵測辨識技術已經是一個比較成熟且應用廣泛的技術。而目前最廣泛的網路應用語言非JS莫屬,在Web前端實現人臉偵測辨識相比後端的人臉辨識有優勢也有弱勢。優點包括減少網路互動、即時識別,大大縮短了使用者等待時間,提高了使用者體驗;弱勢是:受到模型大小限制,其中準確率也有限。如何在web端使用js實現人臉偵測呢?為了實現Web端人臉識別,需要熟悉相關的程式語言和技術,如JavaScript、HTML、CSS、WebRTC等。同時也需要掌握相關的電腦視覺和人工智慧技術。值得注意的是,由於Web端的計

如何使用PHP和JS創建股票蠟燭圖 如何使用PHP和JS創建股票蠟燭圖 Dec 17, 2023 am 08:08 AM

如何使用PHP和JS創建股票蠟燭圖股票蠟燭圖是股票市場中常見的技術分析圖形,透過繪製股票的開盤價、收盤價、最高價和最低價等數據,幫助投資者更直觀地了解股票的價格波動情形。本文將教你如何使用PHP和JS創建股票蠟燭圖,並附上具體的程式碼範例。一、準備工作在開始之前,我們需要準備以下環境:1.一台運行PHP的伺服器2.一個支援HTML5和Canvas的瀏覽器3

股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟 股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟 Dec 17, 2023 pm 06:55 PM

股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟,需要具體程式碼範例隨著網路和科技的快速發展,股票交易已成為許多投資者的重要途徑之一。而股票分析是投資人決策的重要一環,其中蠟燭圖被廣泛應用於技術分析。學習如何使用PHP和JS繪製蠟燭圖將為投資者提供更多直觀的信息,幫助他們更好地做出決策。蠟燭圖是一種以蠟燭形狀來展示股票價格的技術圖表。它展示了股票價格的

PHP Session 跨域問題的解決方法 PHP Session 跨域問題的解決方法 Oct 12, 2023 pm 03:00 PM

PHPSession跨域問題的解決方法在前後端分離的開發中,跨域請求已成為常態。在處理跨域問題時,我們通常會涉及session的使用和管理。然而,由於瀏覽器的同源策略限制,跨域情況下預設無法共享session。為了解決這個問題,我們需要採用一些技巧和方法來實現session的跨域共享。一、使用cookie跨域共享session最常

如何使用JS和百度地圖實現地圖點擊事件處理功能 如何使用JS和百度地圖實現地圖點擊事件處理功能 Nov 21, 2023 am 11:11 AM

如何使用JS和百度地圖實現地圖點擊事件處理功能概述:在網路開發中,經常需要使用地圖功能來展示地理位置和地理資訊。而地圖上的點擊事件處理是地圖功能中常用且重要的一環。本文將介紹如何使用JS和百度地圖API來實現地圖的點擊事件處理功能,並給出具體的程式碼範例。步驟:匯入百度地圖的API檔案首先,要在HTML檔案中匯入百度地圖API的文件,可以透過以下程式碼實現:

如何使用JS和百度地圖實現地圖熱力圖功能 如何使用JS和百度地圖實現地圖熱力圖功能 Nov 21, 2023 am 09:33 AM

如何使用JS和百度地圖實現地圖熱力圖功能簡介:隨著互聯網和行動裝置的快速發展,地圖成為了普遍的應用場景。而熱力圖作為一種視覺化的展示方式,能夠幫助我們更直觀地了解數據的分佈。本文將介紹如何使用JS和百度地圖API來實現地圖熱力圖的功能,並提供具體的程式碼範例。準備工作:在開始之前,你需要準備以下事項:一個百度開發者帳號,並建立一個應用,取得到對應的AP

PHP與JS開發技巧:掌握繪製股票蠟燭圖的方法 PHP與JS開發技巧:掌握繪製股票蠟燭圖的方法 Dec 18, 2023 pm 03:39 PM

隨著網路金融的快速發展,股票投資已經成為了越來越多人的選擇。而在股票交易中,蠟燭圖是常用的技術分析方法,它能夠顯示股票價格的變動趨勢,幫助投資人做出更精準的決策。本文將透過介紹PHP和JS的開發技巧,帶領讀者了解如何繪製股票蠟燭圖,並提供具體的程式碼範例。一、了解股票蠟燭圖在介紹如何繪製股票蠟燭圖之前,我們首先需要先了解什麼是蠟燭圖。蠟燭圖是由日本人

See all articles