Json with Padding只是是解決跨域問題而提出的一種方案。 因爲同源策略的限制,XMLHttpRequest只容許請求前源(域名、協議、端口)的資源,爲了實現跨域請求,能夠經過script標籤實現跨域請求,而後再服務端輸出JSON數據並執行回調函數,從而解決跨域數據請求javascript
通訊原理:首先在客戶端註冊一個callback,而後把callback的名字傳給服務器。此時,服務器先生成json數據,而後以javascript語法的方式,生成function,function名字就是傳遞上來I帶參數jsonp。最後將json數據直接以入參的方式,放置function中,這樣就生成js語法的文檔,返回給客戶端。客戶端瀏覽器,解析script變遷,並執行返回javascript文檔,此時數據做爲參數,傳入了客戶端預先定義好的callback函數裏。簡單的說,就是利用script標籤沒有跨域限制的「漏洞」來達到與第三方通信的目的。php
jsonp 是一種數據調用的方式,帶callback的json就是jsonphtml
jsonp弊端:須要服務端改動參數;只支持get請求;發送的不是xhr請求;java
例:ajax
https://blog.csdn.net/weixin_44083075/article/details/84985147#_4
1. $.ajax({
type: "get",
async: false,
url: "http://t2.com/jsonp.php",
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程序或頁面的,用以得到jsonp回調函數名的參數名(通常默認爲:callback)
jsonpCallback: "localHandler",//自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名,也能夠寫"?",jQuery會自動爲你處理數據
success: function (json) {
$('body').append('<h2>您查詢到航班信息:票價: ' + json.price + ' 元,餘票: ' + json.tickets + ' 張。</h2>');
},
error: function () {
alert('fail');
}
});
json.php
header('Content-Type:application/json; charset=utf-8');
$callback='localHandler';
$data=array(
'price'=>26358,
'tickets'=>56
);
echo $callback.'('.json_encode($data).');';
2.<script type="text/javascript" src="http://localhost/Service.ashx?callback=jsonpCallback" />
//回調函數function jsonpCallback(content){ alert(content); } </script>
運行的結果顯示test jsonp,能夠看出整個過程:
~~~~~~~jsonpCallback的回調函數和ajax中的success中的成功回調均可以操做返回的數據
3.用jQuery中提供的$.getJson方法來跨域訪問。getJson有3個參數:
I. url:請求地址;
II. data:發送到服務端的參數;
III. callback:成功時的回調函數。
PS:getJson的使用方法和普通的$.get方法基本一致,不一樣的地方在於getJson須要在url後面的參數部分加上callback=?這一固定部分,jQuery 將自動替換 ? 爲正確的函數名,以執行回調函數。而後在回調函數中操做從異域返回的json對象,回調函數callback的參數即爲該json對象。
$.getJSON("http://localhost:3561/User/GetAllNames?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
$("#nameList").append("<li>" + json[i] + "</li>");
}
});
** 服務端編寫
服務端的邏輯主要是將數據序列化爲json字符串,而後封裝成"callback(json)"的形式,callback爲jQuery自動生成並傳到服務端的函數名稱。下面使用C#實現:
public class UserController : Controller
{
public string GetAllNames(string callback)
{
string[] names = new string[] { "張三丰", "張無忌", "令狐沖", "楊過", "郭靖" };
JavaScriptSerializer jss = new JavaScriptSerializer();
string json = jss.Serialize(names);
return string.Format("{0}({1})", callback, json);
}
}
思考:若是服務端已經寫死了callback(如:return string.Format("moty({0})", json);),那麼客戶端該怎麼寫呢?
$.ajax("http://localhost:3561/User/GetAllNames", {
jsonpCallback: "moty",
dataType: "jsonp",
success: function(json) {
for (var i = 0; i < json.length; i++) {
$("#nameList").append("<li>" + json[i] + "</li>");
}
}
});
複製代碼
jsonp實現input搜索內容--返回後端數據json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
#wrap {
width: 500px;
margin: 100px auto 0;
}
#wrap input {
width: 486px;
height: 40px;
padding-left: 10px;
}
#list {
margin-top: 10px;
background: #333;
}
#list li {
width: 490px;
line-height: 40px;
background: #ccc;
padding-left: 10px;
margin-bottom: 3px;
}
</style>
</head>
<body>
<div id="wrap">
<input type="text" placeholder="請輸入內容" id="ipt">
<ul id="list">
</ul>
</div>
<script>
var ipt = document.getElementById('ipt'),
list = document.getElementById('list');
var Script = null;
ipt.onkeyup = function () {
if (Script) {
document.body.removeChild(Script);//清除屢次建立script標籤
}
Script = document.createElement('script');
Script.src = 'http://suggestion.baidu.com/su?wd=' + ipt.value + '&cb=mycallbacks&t=' + new Date().getTime();
document.body.appendChild(Script);
}
function mycallbacks(json) { mycallbacks是回調後端動態建立的函數(此函數名可自定義)
list.innerHTML = '';
for (var i = 0; i < json.s.length; i++) {
list.innerHTML += '<li>' + json.s[i] + '</li>';
}
console.log(json);
}
</script>
</body>
</html>
複製代碼