目錄
什麼是跨域?只要協定、網域、連接埠有任何一個不同,都被當作是不同的網域。
跨網域資源共享(CORS)
透過jsonp跨域
JSONP的優缺點
CORS與JSONP對比
透過修改document.domain來跨子域
使用window.name来进行跨域
使用HTML5的window.postMessage方法跨域
首頁 web前端 js教程 用js解決跨域問題實例分享

用js解決跨域問題實例分享

Mar 13, 2018 pm 03:22 PM
javascript 分享 實例

什麼是跨域?只要協定、網域、連接埠有任何一個不同,都被當作是不同的網域。

URL                      说明       是否允许通信
http://www.a.com/a.jshttp://www.a.com/b.js    
 同一域名下   
 允许http://www.a.com/lab/a.jshttp://www.a.com/script/b.js 同一域名下不同文件夹 
 允许http://www.a.com:8000/a.jshttp://www.a.com/b.js     同一域名,不同端口  
 不允许http://www.a.com/a.jshttps://www.a.com/b.js 同一域名,不同协议 
 不允许http://www.a.com/a.jshttp://70.32.92.74/b.js 域名和域名对应ip 
 不允许http://www.a.com/a.jshttp://script.a.com/b.js 主域相同,子域不同 
 不允许http://www.a.com/a.jshttp://a.com/b.js 同一域名,不同二级域名(同上) 
 不允许(cookie这种情况下也不允许访问)http://www.cnblogs.com/a.jshttp://www.a.com/b.js 
 不同域名 不允许
登入後複製

對於連接埠和協定的不同,只能透過後台來解決。

跨網域資源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨網域資源共享,定義了必須在存取跨網域資源時,瀏覽器與伺服器應該如何溝通。 CORS背後的基本想法就是使用自訂的HTTP頭部讓瀏覽器與伺服器溝通,從而決定請求或回應是應該成功還是失敗。

<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "/trigkit4",true);
    xhr.send();</script>
登入後複製

以上的trigkit4是相對路徑,如果我們要使用CORS,相關Ajax程式碼可能如下所示:

<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true);
    xhr.send();</script>
登入後複製

程式碼與之前的差異就在於相對路徑換成了其他域的絕對路徑,也就是你要跨網域存取的介面位址。

伺服器端對於CORS的支持,主要就是透過設定Access-Control-Allow-Origin來進行的。如果瀏覽器偵測到相應的設置,就可以允許Ajax進行跨域的存取。


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

透過jsonp跨域

#現在問題來了?什麼是jsonp?維基百科的定義是:JSONP(JSON with Padding)是資料格式 JSON 的一種“使用模式”,可以讓網頁從別的網域要資料。

JSONP也叫填充式JSON,是應用JSON的新方法,只不過是被包含在函數呼叫中的JSON,例如:

callback({"name","trigkit4"});
登入後複製

JSONP由兩個部分組成:回調函數和數據。回呼函數是當回應到來時應該在頁面中呼叫的函數,而資料就是傳入回呼函數中的JSON資料。

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

<script type="text/javascript">
    function dosomething(jsondata){        //处理获得的json数据
    }</script><script src="http://example.com/data.php?callback=dosomething"></script>
登入後複製

js檔案載入成功後會執行我們在url參數中指定的函數,並且會把我們需要的json資料作為參數傳入。所以jsonp是需要伺服器端的頁面進行對應的配合的。

<?php$callback = $_GET[&#39;callback&#39;];//得到回调函数名$data = array(&#39;a&#39;,&#39;b&#39;,&#39;c&#39;);//要返回的数据echo $callback.&#39;(&#39;.json_encode($data).&#39;)&#39;;//输出?>
登入後複製

最終,輸出結果為:dosomething(['a','b','c']);

如果你的頁面使用jquery,那麼透過它封裝的方法就能很方便的來進行jsonp操作了。

<script type="text/javascript">
    $.getJSON(&#39;http://example.com/data.php?callback=?,function(jsondata)&#39;){        //处理获得的json数据
    });</script>
登入後複製

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

JSONP的優缺點

JSONP的優點是:它不像XMLHttpRequest物件實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更古老的瀏覽器中都可以運行,不需要XMLHttpRequest或ActiveX的支援;並且在請求完畢後可以透過呼叫callback的方式回傳結果。

JSONP的缺點則是:它只支援GET請求而不支援POST等其它類型的HTTP請求;它只支援跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript呼叫的問題。

CORS與JSONP對比

CORS與JSONP相比,無疑更為先進、方便、可靠。

    1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
    2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
    3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。
登入後複製

透過修改document.domain來跨子域

瀏覽器都有一個同源策略,其限制之一就是第一種方法中我們說的不能透過ajax的方法去請求不同來源中的文件。 它的第二個限制是瀏覽器中不同域的框架之間是不能進行js的交互操作的。
不同的框架之間是可以取得window物件的,但卻無法取得對應的屬性和方法。例如,有一個頁面,它的地址是http://www.example.com/a.html , 在這個頁面裡面有一個iframe,它的src是http://example.com/b.html, 很顯然,這個頁面與它裡面的iframe框架是不同域的,所以我們是無法透過在頁面中書寫js程式碼來取得iframe中的東西的:

<script type="text/javascript">
    function test(){        var iframe = document.getElementById(&#39;ifame&#39;);        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }</script><iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
登入後複製

這個時候,document.domain就可以派上用場了,我們只要把http://www.example.com/a.html 和 http://example.com/b.html這兩個頁面的document.domain都設成相同的網域就可以了。但要注意的是,document.domain的設定是有限制的,我們只能把document.domain設定成自身或更高一級的父域,而主域必須相同。

1.在页面 http://www.example.com/a.html 中设置document.domain:

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe><script type="text/javascript">
    document.domain = &#39;example.com&#39;;//设置成主域
    function test(){
        alert(document.getElementById(&#39;iframe&#39;).contentWindow);//contentWindow 可取得子窗口的 window 对象
    }</script>
登入後複製

2.在页面 http://example.com/b.html 中也设置document.domain:

<script type="text/javascript">
    document.domain = &#39;example.com&#39;;//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同</script>
登入後複製

修改document.domain的方法只适用于不同子域的框架间的交互。

使用window.name来进行跨域

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的

使用HTML5的window.postMessage方法跨域

window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

相关推荐:

php关于ajax跨域问题解析

关于javascript中跨域问题的解决办法分享

关于js跨域问题的总结

以上是用js解決跨域問題實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

夸克網盤怎麼分享到百度網盤? 夸克網盤怎麼分享到百度網盤? Mar 14, 2024 pm 04:40 PM

  夸克網盤和百度網盤都是很便利的儲存工具,不少的用戶都在詢問這兩款軟體互通嗎?夸克網盤怎麼分享到百度網盤?下面就讓本站來為用戶們來仔細的介紹一下夸克網盤的文件怎麼保存到百度網盤方法吧。夸克網盤的文件怎麼保存到百度網盤方法1、想要知道怎麼把夸克網盤的文件轉到百度網盤,首先在夸克網盤上下載需要保存的文件,然後打開百度網盤客戶端後,選擇壓縮檔案要儲存的資料夾,雙擊開啟該資料夾。  2、開啟該資料夾後,點選視窗左上角區域的「上傳」。  3、在電腦中找到需要上傳的壓縮文件,點選選

網路易雲音樂怎麼分享到微信朋友圈_網易雲音樂分享到微信朋友圈教程 網路易雲音樂怎麼分享到微信朋友圈_網易雲音樂分享到微信朋友圈教程 Mar 25, 2024 am 11:41 AM

1.首先我們進入到網易雲音樂中,然後在軟體首頁介面中,點選進入到歌曲的播放介面中。 2.然後在歌曲播放介面中,找到右上方的分享功能按鈕,如下圖紅框所示位置,點擊選擇分享的管道;在分享管道中,點擊底部的「分享至」選項,然後選擇第一個“微信朋友圈”,即可將內容分享至微信朋友圈。

百度網盤怎麼分享文件給好友 百度網盤怎麼分享文件給好友 Mar 25, 2024 pm 06:52 PM

近期,百度網盤安卓客戶端迎來了全新的8.0.0版本,這個版本不僅帶來了許多變化,還增添了許多實用功能。其中,最引人注目的便是資料夾共享功能的增強。現在,使用者可以輕鬆邀請好友加入,共同分享工作與生活中的重要文件,實現更便利的協作與分享。那麼究竟該如何分享給好友自己需要分享的文件呢,下文中本站小編就會為大家帶來詳細內容介紹,希望能幫助大家! 1)開啟百度雲APP,先點選在首頁選擇相關的資料夾,再點選介面右上角的【...】圖示;(如下圖)2)接著點選「共用成員」一欄中的【+ 】,最後在勾選所

芒果tv會員帳號分享2023 芒果tv會員帳號分享2023 Feb 07, 2024 pm 02:27 PM

芒果TV擁有各種類型的電影、電視劇、綜藝等資源,用戶可以在其中自由的選擇觀看。芒果tv會員不僅能夠看到全部的VIP劇而且還能夠設定最高清的畫質,幫助用戶爽快看劇,下面小編就給大家帶來一些芒果tv免費的會員帳號供用戶們使用,趕緊來看一看吧。芒果tv最新會員帳號免費分享2023:注意:都是收集的最新會員帳號,可以直接登入使用,不要隨意的修改密碼。帳號:13842025699密碼:qds373帳號:15804882888密碼:evr6982帳號:13330925667密碼:jgqae帳號:1703

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

分享惠普印表機驅動的兩種安裝方法 分享惠普印表機驅動的兩種安裝方法 Mar 13, 2024 pm 05:16 PM

  惠普印表機是許多辦公室內必備的列印設備,在電腦上安裝印表機驅動,可以完美解決印表機無法連線等等問題。那麼惠普印表機驅動程式要怎麼安裝?下面小編就跟大家介紹兩個惠普印表機驅動程式安裝方法。  第一種方法:官網下載驅動  1、在搜尋引擎中搜尋惠普中國官網,在支援一欄中,選擇【軟體與驅動程式】。  2、選擇【印表機】分類,在搜尋框中輸入你的印表機型號,點選【提交】,即可查找到你的印表機驅動程式。  3、根據你電腦的系統選擇對應的印表機,win10即選擇win10系統的驅動程式。  4、下載成功後,在資料夾中找到

番茄小說連結如何分享 番茄小說連結如何分享 Feb 27, 2024 pm 04:20 PM

番茄小說是豐富的小說寶庫,其中匯集了大量優質的小說資源。在這裡,你可以依照自己的喜好,從多種不同類型的小說中挑選出心儀之作。對於熱愛閱讀的你,這無疑是一片可以自由翱翔的文學天地。有的時候遇到心儀的讀物也像分享給好友一起閱讀,但是很多用戶們還不清楚究竟該如何分享,那麼這篇教程攻略就將為大家帶來詳細的攻略介紹,想要了解的玩家們就快來跟著本文一起閱讀吧!番茄小說怎麼分享書給好友? 1.打開番茄小說,點選進入小說,點選右上角分享圖示。 2.選擇分享管道,這裡小編以分享至微信好友為例。 3、點擊分享。 4、即可查

解決Discuz微信分享無法顯示的問題 解決Discuz微信分享無法顯示的問題 Mar 09, 2024 pm 03:39 PM

標題:解決Discuz微信分享無法顯示的問題,需要具體程式碼範例隨著行動網路的發展,微信成為了人們日常生活中不可或缺的一部分。在網站開發中,為了提升使用者體驗和擴大網站的曝光度,許多網站會整合微信分享功能,讓使用者能夠輕鬆分享網站的內容到朋友圈或微信群組。然而,有時在使用Discuz等開源論壇系統時,會遇到微信分享無法顯示的問題,這給使用者體驗帶來了一定的困

See all articles