我瞭解JSON,但不瞭解JSONP。 Wikipedia上有關JSON的文檔是JSONP的最高搜索結果。 它說: javascript
JSONP或「帶填充的JSON」是JSON擴展,其中將前綴指定爲調用自己的輸入參數。 php
?? 什麼電話 這對我來講毫無心義。 JSON是一種數據格式。 沒有電話 html
第二個搜索結果來自一個叫Remy的人 ,他寫了關於JSONP的代碼: java
JSONP是腳本標記注入,它未來自服務器的響應傳遞到用戶指定的函數。 json
我能夠理解,但這仍然沒有任何意義。 api
那麼JSONP是什麼? 爲何建立它(它解決了什麼問題)? 我爲何要使用它? 跨域
附錄 :我剛剛在Wikipedia 上爲JSONP建立了一個新頁面 。 根據jvenema的回答,它如今對JSONP有了清晰而透徹的描述。 瀏覽器
JSONP經過構造一個「腳本」元素(以HTML標記或經過JavaScript插入DOM)來工做,該元素請求到遠程數據服務位置。 響應是使用預約義函數名稱以及所傳遞的參數(即請求的JSON數據)加載到瀏覽器上的JavaScript。 執行腳本時,該函數將與JSON數據一塊兒調用,從而容許請求頁面接收和處理數據。 安全
有關進一步的閱讀訪問, 請 訪問: https : //blogs.sap.com/2013/07/15/secret-behind-jsonp/ 服務器
客戶端代碼段
<!DOCTYPE html> <html lang="en"> <head> <title>AvLabz - CORS : The Secrets Behind JSONP </title> <meta charset="UTF-8" /> </head> <body> <input type="text" id="username" placeholder="Enter Your Name"/> <button type="submit" onclick="sendRequest()"> Send Request to Server </button> <script> "use strict"; //Construct the script tag at Runtime function requestServerCall(url) { var head = document.head; var script = document.createElement("script"); script.setAttribute("src", url); head.appendChild(script); head.removeChild(script); } //Predefined callback function function jsonpCallback(data) { alert(data.message); // Response data from the server } //Reference to the input field var username = document.getElementById("username"); //Send Request to Server function sendRequest() { // Edit with your Web Service URL requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+""); } </script> </body> </html>
服務器端的一段PHP代碼
<?php header("Content-Type: application/javascript"); $callback = $_GET["callback"]; $message = $_GET["message"]." you got a response from server yipeee!!!"; $jsonResponse = "{\"message\":\"" . $message . "\"}"; echo $callback . "(" . $jsonResponse . ")"; ?>
JSONP能夠很好地解決跨域腳本錯誤。 您能夠只使用JS來使用JSONP服務,而沒必要在服務器端實現AJAX代理。
您可使用b1t.co服務查看其工做方式。 這是一項免費的JSONP服務,可以讓您縮小URL。 這是用於服務的網址:
http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]
例如,呼叫http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com
會回來
whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});
所以,當將該get做爲src加載到您的js中時,它將自動運行您應將其實現爲回調函數的任何JavascriptName:
function minifyResultsCallBack(data) { document.getElementById("results").innerHTML = JSON.stringify(data); }
要真正進行JSONP調用,您能夠經過幾種方式(包括使用jQuery)來實現,但這是一個純JS示例:
function minify(urlToMinify) { url = escape(urlToMinify); var s = document.createElement('script'); s.id = 'dynScript'; s.type='text/javascript'; s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url; document.getElementsByTagName('head')[0].appendChild(s); }
這篇文章提供了一個分步示例和一個jsonp Web服務進行練習:
由於您能夠要求服務器將前綴附加到返回的JSON對象。 例如
function_prefix(json_object);
爲了使瀏覽器eval
「內聯」 JSON字符串做爲表達式。 此技巧使服務器能夠直接在客戶端瀏覽器中「注入」 javascript代碼,而且繞過了「相同來源」限制。
換句話說,您能夠進行跨域數據交換 。
一般, XMLHttpRequest
不容許直接進行跨域數據交換(須要經過同一域中的服務器),而:
<script src="some_other_domain/some_data.js&prefix=function_prefix
>`人們能夠從不一樣於來源的域訪問數據。
一樣值得注意的是:即便在嘗試這種「技巧」以前,應將服務器視爲「受信任的」服務器,也能夠包含對象格式等可能發生變化的反作用。 若是使用function_prefix
(即適當的js函數)來接收JSON對象,則該函數能夠在接受/進一步處理返回的數據以前執行檢查。
實際上並不太複雜...
假設您使用的是example.com
域,而且想向example.net
域發出請求。 要作到這一點,你須要跨域邊界, 無無多數browserland的。
繞過此限制的一項是<script>
標記。 使用腳本標記時,將忽略域限制,可是在正常狀況下,您實際上沒法對結果作任何事情,只是對腳本進行了評估。
輸入JSONP
。 當您向啓用JSONP的服務器發出請求時,您將傳遞一個特殊參數,該參數告訴服務器有關您頁面的一些信息。 這樣,服務器就能夠用頁面能夠處理的方式很好地包裝其響應。
例如,假設服務器須要一個名爲callback
的參數來啓用其JSONP功能。 而後您的請求將以下所示:
http://www.example.net/sample.aspx?callback=mycallback
沒有JSONP,這可能會返回一些基本的JavaScript對象,以下所示:
{ foo: 'bar' }
可是,使用JSONP時,服務器收到「 callback」參數時,其包裝結果會有所不一樣,返回以下所示:
mycallback({ foo: 'bar' });
如您所見,它如今將調用您指定的方法。 所以,在頁面中,您定義了回調函數:
mycallback = function(data){ alert(data.foo); };
如今,加載腳本後,將對其進行評估,而後將執行您的函數。 瞧,跨網域要求!
值得注意的是JSONP的一個主要問題:您失去了對請求的大量控制。 例如,沒有「不錯」的方法來找回正確的故障代碼。 結果,您最終會使用計時器來監視請求等,這老是讓人懷疑。 JSONRequest的主張是一個很好的解決方案,它容許跨域腳本編寫,維護安全性並容許對請求的適當控制。
現在(2015年),與JSONRequest相比, CORS是推薦的方法。 JSONP對於較舊的瀏覽器支持仍然有用,可是考慮到安全隱患,除非您別無選擇,不然CORS是更好的選擇。
一個使用JSONP的簡單示例。
client.html
<html> <head> </head> body> <input type="button" id="001" onclick=gO("getCompany") value="Company" /> <input type="button" id="002" onclick=gO("getPosition") value="Position"/> <h3> <div id="101"> </div> </h3> <script type="text/javascript"> var elem=document.getElementById("101"); function gO(callback){ script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'http://localhost/test/server.php?callback='+callback; elem.appendChild(script); elem.removeChild(script); } function getCompany(data){ var message="The company you work for is "+data.company +"<img src='"+data.image+"'/ >"; elem.innerHTML=message; } function getPosition(data){ var message="The position you are offered is "+data.position; elem.innerHTML=message; } </script> </body> </html>
server.php
<?php $callback=$_GET["callback"]; echo $callback; if($callback=='getCompany') $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})"; else $response="({\"position\":\"Development Intern\"})"; echo $response; ?>