2012-04-17 103 views
17

我無法理解jsonp請求如何工作的細節。我已經閱讀了包括jsonp上的維基在內的多個資源,並且我仍然非常困惑,在進行jsonp調用時,回調實際上如何獲得從服務器返回的函數的保留。例如,在wiki中,請求的來源設置爲:困惑於JSONP請求如何工作

src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse" 

究竟是什麼jsonp = parseResponse實際上是指/?然後他們繼續說有效載荷是:

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

這是如何工作的?我對整個回調函數感到困惑。函數名稱parseResponse被傳遞給服務器,並且返回的數據以某種方式成爲這個函數的參數?有人能夠清楚地解釋數據是如何從jsonp請求中檢索/使用的嗎?

+0

可能重複[請解釋JSONP](http://stackoverflow.com/questions/2067472/please-explain-jsonp) – Jon 2012-04-17 14:27:13

回答

40

回調是一個函數,你'VE在您自己的代碼中定義。 jsonp服務器將用與指定的回調函數相同的函數調用來包裝其響應。

會發生什麼事是這樣的:

1)你的代碼創建JSONP請求,這將導致一個新的<script>塊,看起來像這樣:

<script src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"></script> 

2)這新的腳本被執行您的瀏覽器,導致對JSONP服務器的請求。它與

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

3迴應),因爲這要求從腳本標籤來了,這幾乎是完全一樣的,如果你想從字面上放置

<script> 
    parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 
</script> 

到您的網頁。

4)現在這個新的腳本已經從遠程服務器加載,現在它將被執行,它將做的唯一的事情是一個函數調用,parseResponse(),傳入JSON數據作爲函數調用的唯一參數。

因此,在你的代碼別的地方,你必須:

function parseResponse(data) { 
    alert(data.Name); // outputs 'Foo' 
} 

基本上,JSONP是繞過瀏覽器的同源腳本安全策略,由具有第三方服務器注入函數調用的方式直接進入你的頁面。請注意,這在設計上非常不安全。您認爲遠程服務是光榮的,並沒有惡意的意圖。沒有什麼能夠阻止一些糟糕的服務返回一些JS代碼來竊取你的銀行/臉書/任何憑據。例如...... JSONP響應可能是

internalUseOnlyFunction('deleteHarddrive'); 

而不是parseReponse(...)。如果遠程站點知道你的代碼的結構,它可以使用該代碼執行任意操作,因爲你已經打開了前門,允許該站點執行任何想要的操作。

+8

我不會像'deleteHardDrive'那樣舉一個例子(javascript無法在瀏覽器中做到這一點),但絕對值得注意的是,這可能是危險的。 – hitautodestruct 2013-11-12 13:48:37

+1

很好的解釋! – FloatingRock 2014-09-19 16:10:59

1

編輯:正如喬恩所說,有一個更好的解釋方法here

JSONP使用腳本標記進行跨源請求。由於腳本標記用於包含腳本,因此服務器需要返回有效的JavaScript。我們將JavaScript提供給客戶端的方式是通過函數調用。你告訴服務器你希望腳本調用什麼功能,然後在本地創建該功能。當腳本加載完成後,您的函數將以數據作爲參數被調用。

所以,如果你沒有在你所提到的URL JSONP請求,並返回你所提到的有效載荷,你會被這樣獲取您的數據:

function parseResponse(data) { 
    console.log("JSONP request complete", data); 
} 
+0

數據返回如何神奇地成爲parseRepsonse函數的參數? – 2012-04-17 14:30:47

+0

@JohnBaum因爲服務器創建將被調用的JS代碼? – 2012-04-17 15:10:16

0

函數名parseResponse傳遞到服務器,並以某種方式 返回的數據變爲參數,這個功能

看起來你只是你自己解釋它,jsonp=parseResponse是這個應用程序是如何設置的回調函數,所以它返回一個FUNC重刑與它的JSON數據,看起來像

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7}); 

當它被加載,並會通過函數在JS像處理被稱爲:

function parseResponse(data){ 
    console.log(data); 
}