JS、Jquery裏面的jsonp

參考個人博客:http://www.zhuzhuman.com/nav-1/type-1/article/20.html
      我們平常使用ajax從前端發起請求獲取數據,一般請求的地址都是和當前網頁是同源的,即不能進行跨域請求,(跨域:主域名、子域名、端口號其中有一個不同就屬於跨域);
      Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。
      雖然普通ajax不能跨域,但是script標籤是可以跨域引用的,即JS可以跨域使用。因此:
      jsonp實現跨域請求數據的原理:jsonp允許服務器在後臺生成一段js代碼(回調函數),將數據寫進回調函數裏,然後返回給頁面,頁面接收回調函數後在頁面執行,可獲取到數據。注:因此,jsonp返回給頁面的不是數據本身,而是回調函數,數據可從回調函數中獲取。

舉例:

  1. jquery寫法:
    第一種寫法:ajax
<script type="text/javascript">
	// 前端通過jquery發起ajax請求
	$.ajax({
		type : "GET", // 獲取方式,好像jsonp不支持post...
		url : "http://127.0.0.1/jsonp/jsonp.php", // 請求的地址
		async:false, // 同步
		dataType : "jsonp", // 數據類型,必須是jsonp,這樣才能進行跨域操作
		data : "", // 傳給後臺的數據,可省略。
		jsonp : "callback", // 用於指定回調函數,可爲任意名字,但是必須和後臺用GET獲取用的名字保持一致。
		jsonpCallback : "myCallBack", // 自定義回調函數名,可省略,默認jq會自動隨機生成函數名傳給後臺。
		success : function (data) { // 請求成功時執行的函數,其中data就是後臺數據。
			console.log(data); 
		},
		error : function (e) {
			console.log("e");
		}
	})
</script>

第二種寫法: get請求

<script type="text/javascript">
	$.getJSON('http://127.0.0.1/jsonp/jsonp.php?callback=?',function (data) {
		console.log(data);
	}); // ?後面的callback=?用來標識是jsonp請求。其中callback必須和後臺get獲取數據時用的名字一樣。
</script>

2.原生JS實現jsonp

function jsonp(options) {
	// 請求參數設置
	options = options || {};
	// 創建js標籤用於執行jsonp
    var oHead = document.getElementsByTagName('head')[0];
    var oScript = document.createElement('script');
    // 給window綁定和callback參數值相同的函數,用於獲數據
    var _callback = options.callback;
    window[_callback] = function (data) {
    	// 形參data 用於接收後臺返回的 callback函數 的實參(數據)
    	// 獲取數據成功後清除jsonp的js
    	oHead.removeChild(oScript);
    	// 清除加載超時的定時函數(加載成功,超時函數不用執行了)
    	clearTimeout(oScript.timer);
    	// 清除回調函數
    	window[_callback] = null;
    	// 執行請求成功的回調函數,把callback裏的參數再傳給succeed函數。succeed 函數裏面執行對數據的操作
    	options.success && options.success(data);
    }
    // js發起請求,請求成功後返回的代碼是讓 callback 執行的,而且實參就是後臺數據
    var url = options.url.indexOf('?') > -1 ? options.url + '&callback=' + options.callback : options.url + '?callback=' + options.callback;
    if(options.data) {
    	for(var k in options.data) {
    		url += '&' + k + '=' + options.data[k];
		}
    }
    oScript.src = url;
    oHead.appendChild(oScript);
    // 超時函數,請求超時走error邏輯
    if (options.timeout) {
    	oScript.timer = setTimeout(function() {
    		// 錯誤後清除回調函數
    		window[_callback] = null;
    		oHead.removeChild(oScript);
    		// 執行error函數
    		options.error && options.error({ message: "超時" });
    	}, options.timeout * 1000);
    }
};

// 測試執行
var params = {
	url: 'http://127.0.0.1/jsonp/jsonp.php',
	callback: 'getback',
	timeout: 10,
	data: {
		param1: 'a',
		param2: 'b'
	},
	success: function(data) {
		console.log(data);
	},
	error: function(e) {
		console.log(e);
	}	
}; // 其他參數配置可根據需求添加
jsonp(params);
  1. 後臺文件jsonp.php寫法
<?php
	// 要返回的數據
	$data = '{
		"shuju1" : "1",
		"shuju2" : "2",
		"shuju3" : "3",
		"shuju4" : "4",
		"shuju5" : "5"
	}';

	// 獲取請求傳過來的值,用於定義要返回的回調函數名,
	$callback = $_GET['callback']; // 中括號裏的'callback',必須和前端ajax裏的的jsonp:"callback",中jsonp的值名字一樣

	// 將回調函數名和數據拼接成函數的形式。數據以入參的形式傳入。
	echo $callback . "(" . $data . ")";
?>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章