首頁 web前端 js教程 深入分析JSONP跨域的原理_基礎知識

深入分析JSONP跨域的原理_基礎知識

May 16, 2016 pm 04:27 PM
jsonp 跨域

JavaScript是一種在Web開發中經常使用的前端動態腳本技術。在JavaScript中,有一個很重要的安全性限制,被稱為「Same- Origin Policy」(同源策略)。這個策略對於JavaScript程式碼能夠存取的頁面內容做了很重要的限制,即JavaScript只能存取與包含它的文件 在同一網域下的內容。

JavaScript這個安全策略在進行多iframe或多視窗程式設計、以及Ajax程式設計時顯得特別重要。根據這個策略,在baidu.com下的 頁面中包含的JavaScript程式碼,不能存取在google.com網域下的頁面內容;甚至不同的子網域之間的頁面也不能透過JavaScript代 碼互相存取。對於Ajax的影響在於,透過XMLHttpRequest實現的Ajax請求,不能向不同的網域提交請求,例如,在 abc.example.com下的頁面,不能向def.example.com提交Ajax請求,等等。

然而,當進行一些比較深入的前端程式設計的時候,不可避免地需要進行跨域操作,這時候「同源策略」就顯得過於苛刻。 JSONP跨域GET請求是常用的解決方案,以下我們來看看JSONP跨域是如何實現的,並且探討下JSONP跨域的原理。

利用在頁面中建立<script>節點的方法向不同網域提交HTTP請求的方法稱為JSONP,這項技術可以解決跨域提交Ajax請求的問題。 JSONP的工作原理如下所述:</script>

假設在http://example1.com/index.php這個頁面中向http://example2.com /getinfo.php提交GET請求,我們可以將下面的JavaScript程式碼放在http://example1.com/index.php這個頁面中來實作:

複製程式碼 程式碼如下:

var eleScript= document.createElement("script");
eleScript.type = "text/javascript";
eleScript.src = "http://example2.com/getinfo.php";
document.getElementsByTagName("HEAD")[0].appendChild(eleScript);

當GET要求從http://example2.com/getinfo.php回傳時,可以回傳一段JavaScript程式碼,這段程式碼會自動執行,可以用來負責呼叫http: //example1.com/index.php頁面中的一個callback函數。

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

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

再來一個例子:

複製程式碼 程式碼如下:

var qsData = {'searchWord':$("#searchWord").attr("value"),'currentUserId':
$("#currentUserId").attr("value"),'conditionBean.pageSize':$("#pageSize").attr("value")};
$.ajax({
    async:false,
    url: http://跨域的dns/document!searchJSONResult.action,
    type: "GET",
    dataType: 'jsonp',
    jsonp: 'jsoncallback',
    data: qsData,
    timeout: 5000,
    beforeSend: function(){
        //jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了
    },
    success: function (json) {//客戶端jquery預先定義好的callback函數,成功取得跨網域伺服器上的json資料後,會動態執行這個callback函數
        if(json.actionErrors.length!=0){
            alert(json.actionErrors);
        }
        genDynamicContent(qsData,type,json);
    },
    complete: function(XMLHttpRequest, textStatus){
        $.unblockUI({ fadeOut: 10 });
    },
    error: function(xhr){
        //jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了
        //請求錯誤處理
        alert("請求出錯(請檢查相關度網路狀況.)");
    }
});

有時也會看到這樣的寫法:

複製程式碼 程式碼如下:

$.getJSON("http://跨域的dns/document!searchJSONResult.action?name1=" value1 "&jsoncallback=?",
    function(json){
    if(json.屬性名==值){
        // 執行碼
    }
});

這種方式其實是上例$.ajax({..}) api的一種高階封裝,有些$.ajax api底層的參數就被封裝而不可見了。

這樣,jquery就會拼成如下的url get請求:

複製程式碼 程式碼如下:

http://跨域的dns/document!searchJSONResult.action?&jsoncallback=jsonp1236827957501&_=1236828192549&searchWord=
用例¤tUserId=5351&conditionBean.pageSize=15

在回應端(http://跨域的dns/document!searchJSONResult.action),透過jsoncallback = request.getParameter("jsoncallback") 得到jquery端隨後要回呼的js function name:jsonp1236827957501response為一個Script Tags:"jsonp1236827957501(" 按請求參數產生的json數組")"; jquery就會透過回呼方法動態載入呼叫這個js tag:jsonp1236827957501(json數組); 這樣就達到了跨域資料交換的目的。

JSONP原理

JSONP的最基本的原理是:動態添加一個<script>標籤,而script標籤的src屬性是沒有跨域的限制的。這樣說來,這種跨域方式其實與ajax XmlHttpRequest協定無關了。 </script>

這樣其實"jQuery AJAX跨域問題"就成了個偽命題,jquery $.ajax方法名有誤導人之嫌。

如果設為dataType: 'jsonp',這個$.ajax方法就和ajax XmlHttpRequest沒什麼關係了,取而代之的則是JSONP協議。 JSONP是一個非官方的協議,它允許在伺服器端整合Script tags返回到客戶端,透過javascript callback的形式實現跨域存取。

JSONP即JSON with Padding。由於同源策略的限制,XmlHttpRequest只允許請求目前來源(網域名稱、協定、連接埠)的資源。如果要進行跨域請求, 我們可以透過使用html的script標記來進行跨域請求,並在回應中傳回要執行的script程式碼,其中可以直接使用JSON傳遞 javascript物件。 這種跨域的通訊方式稱為JSONP。

jsonCallback 函數jsonp1236827957501(....):是瀏覽器客戶端註冊的,取得跨網域伺服器上的json資料後,回呼的函數

Jsonp的執行過程如下:

先在客戶端註冊一個callback (如:'jsoncallback'), 然後把callback的名字(如:jsonp1236827957501)傳給伺服器。注意:服務端得到callback的數值後,要用 jsonp1236827957501(......)把將要輸出的json內容包括起來,此時,伺服器產生 json 資料才能被客戶端正確接收。

然後以 javascript 語法的方式,產生一個function, function 名字就是傳遞上來的參數 'jsoncallback'的值 jsonp1236827957501 .

最後將 json 資料直接以入參的方式,放置到 function 中,這樣就產生了一段 js 語法的文檔,返回給客戶端。

客戶端瀏覽器,解析script標籤,並執行返回的javascript 文檔,此時javascript文檔數據,作為參數, 傳入到了客戶端預先定義好的callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裡。

可以說jsonp的方式原理上和是一致的(qq空間就是大量採用這種方式來實現跨域資料交換的)。 JSONP是一種腳本注入(Script Injection)行為,所以有一定的安全隱憂。

jquery為什麼不支援post方式跨域呢?

雖然採用post 動態生成iframe是可以達到post跨域的目的(有位js牛人就是這樣把jquery1.2.5 打patch的),但這樣做是一個比較極端的方式,不建議採用。

也可以說get方式的跨域是合法的,post方式從安全角度上,被認為是不合法的,萬不得已還是不要劍走偏鋒。

client端跨域存取的需求看來也引起w3c的注意了,看資料說html5 WebSocket標準支援跨域的資料交換,應該也是一個將來可選的跨域資料交換的解決方案。

來個超簡單的例子:

複製程式碼 程式碼如下:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
http://www.w3.org/1999/xhtml" >
Jsonp をテスト <スクリプトタイプ="text/javascript"> 関数 jsonpCallback(result)
                                                                 アラート(結果.msg);                                                                                                                                                                                                                  

熱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)

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

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

Vue 中如何進行跨域請求? Vue 中如何進行跨域請求? Jun 10, 2023 pm 10:30 PM

Vue是一種流行的JavaScript框架,用於建立現代化的Web應用程式。在使用Vue開發應用程式時,常常需要與不同的API交互,而這些API往往位於不同的伺服器上。由於跨域安全性策略的限制,當Vue應用程式在一個網域上運行時,它不能直接與另一個網域上的API進行通訊。本文將介紹幾種在Vue中進行跨域請求的方法。 1.使用代理常見的跨域解決方案是使用代理

如何使用Flask-CORS實現跨域資源共享 如何使用Flask-CORS實現跨域資源共享 Aug 02, 2023 pm 02:03 PM

如何使用Flask-CORS實現跨域資源共享引言:在網路應用開發中,跨域資源共享(CrossOriginResourceSharing,簡稱CORS)是一種機制,允許伺服器與指定的來源或網域名稱之間共享資源。使用CORS,我們可以靈活地控制不同域之間的資料傳輸,實現安全、可靠的跨域存取。在本文中,我們將介紹如何使用Flask-CORS擴充庫來實現CORS功

Vue中如何利用JSONP實作跨域請求 Vue中如何利用JSONP實作跨域請求 Oct 15, 2023 pm 03:52 PM

Vue中如何利用JSONP實現跨域請求簡介由於同源策略的限制,前端在進行跨域請求時會受到一定的阻礙。 JSONP(JSONwithPadding)是一種跨域請求的方法,它利用&lt;script&gt;標籤的特性,透過動態建立&lt;script&gt;標籤來實現跨域請求,並將回應資料作為回呼函數的參數傳遞回來。本文將詳細介紹在Vue中如何利用JSONP實

如何在HTML中允許跨域使用影像和畫布? 如何在HTML中允許跨域使用影像和畫布? Aug 30, 2023 pm 04:25 PM

為了允許跨網域使用影像和畫布,伺服器必須在其HTTP回應中包含適當的CORS(跨網域資源共用)頭。這些頭可以設定為允許特定的來源或方法,或允許任何來源存取資源。 HTMLCanvasAnHTML5CanvasisarectangularareaonawebpagethatiscontrolledbyJavaScriptcode.Anythingcanbedrawnonthecanvas,includingimages,shapes,text,andanimations.Thecanvasisagre

Vue技術開發中遇到的跨域問題及解決方法 Vue技術開發中遇到的跨域問題及解決方法 Oct 08, 2023 pm 09:36 PM

Vue技術開發中遇到的跨域問題及解決方法摘要:本文將介紹在Vue技術開發過程中,可能遇到的跨域問題以及解決方法。我們將從導致跨域的原因開始,然後介紹幾種常見的解決方案,並提供具體程式碼範例。一、跨域問題的原因在網路開發中,由於瀏覽器的安全策略,瀏覽器會限制從一個來源(網域、協定或連接埠)請求另一個來源的資源。這就是所謂的「同源策略」。當我們在Vue技術開發中,前端與

在Beego框架中使用CORS解決跨域問題 在Beego框架中使用CORS解決跨域問題 Jun 04, 2023 pm 07:40 PM

隨著Web應用程式的發展和互聯網的全球化,越來越多的應用程式需要進行跨域請求。對於前端開發人員而言,跨域請求是一個常見的問題,它可能導致應用程式無法正常運作。在這種情況下,解決跨域請求問題的最佳方法之一是使用CORS。在本文中,我們將重點放在如何在Beego框架中使用CORS來解決跨域問題。什麼是跨域請求?在網路應用程式中,跨網域請求是指從一個網域的網頁向另一

PHP Session 跨域的跨平台相容性處理 PHP Session 跨域的跨平台相容性處理 Oct 12, 2023 am 09:46 AM

PHPSession跨域的跨平台相容性處理隨著Web應用程式的發展,越來越多的開發者面臨跨域的問題。跨域是指在一個網域下的網頁去請求另一個網域下的資源,這在一定程度上增加了開發難度,特別是對於涉及到會話(Session)管理的應用程式來說,更是一個棘手的問題。本文將介紹如何在PHP中處理跨域的會話管理,並提供一些具體的程式碼範例。會話管理是We

See all articles