跨站請求資料jsonp手寫原生js程式碼實現
阿新 • • 發佈:2019-01-04
JSONP
--來自百度百科
JSONP(JSON with Padding)是JSON的一種“使用模式”,可用於解決主流瀏覽器的跨域資料訪問的問題。由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
關於HTML幾種標籤能否獲取資料的說明:
<!-- 早期用於統計連結,支援跨域但是無法實現獲取服務端返回的資料 -->
<img src="http://www.baidu.com?id=xxx">
<!-- 支援,可以接受服務端資料,但過程複雜 -->
<iframe src="http://www.baidu.com?id=xxx" frameborder="0"></iframe>
<!-- 會在css處理階段報錯 -->
<link rel="stylesheet" href="http://www.baidu.com?id=xxx">
<!-- script可以接受資料並處理 -->
<script src="http://www.baidu.com?id=xxx"></script>
<!-- callback({}) -->
原生js實現jsonp跨站獲取資料:
var jsonp = function(url,data,callback){ // 回撥函式+時間戳 var cbName = 'callback_' + new Date().getTime(); // 暴露全域性函式給window // 判讀查詢字串最後一位是否為?或者是& var queryString = url.indexOf('?') == -1 ? '?' : '&'; // 遍歷傳進來的data實參賦值給查詢字串 for(var k in data){ queryString += k + '=' + data[k] + '&'; } // 查詢字串加上回調函式 queryString += 'callback=' + cbName; // 建立script標籤 var ele = document[0].createElement('script'); // 給script標籤新增src屬性值 ele.src = url + queryString; window[cbName] = function(data){ callback(data); document[0].body.removeChild(ele); }; // 新增到body尾部 document[0].body.appendChild(ele); }
使用方法:
$jsonp('http://api.douban.com/v2/movie/in_theaters',{
'count':1
},function(data){
document.getElementsByTagName('body')[0].innerHTML = JSON.stringify(data);
})
html結構:<div id="result"></div>
完整程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp</title>
</head>
<body>
<div id="result"></div>
<script>
(function(window,document,undefined){
var jsonp = function(url,data,callback){
// 回撥函式+時間戳
var cbName = 'callback_' + new Date().getTime();
// 暴露全域性函式給window
// 判讀查詢字串最後一位是否為?或者是&
var queryString = url.indexOf('?') == -1 ? '?' : '&';
// 遍歷傳進來的data實參賦值給查詢字串
for(var k in data){
queryString += k + '=' + data[k] + '&';
}
// 查詢字串加上回調函式
queryString += 'callback=' + cbName;
// 建立script標籤
var ele = document[0].createElement('script');
// 給script標籤新增src屬性值
ele.src = url + queryString;
window[cbName] = function(data){
callback(data);
document[0].body.removeChild(ele);
};
// 新增到body尾部
document[0].body.appendChild(ele);
}
//jsonp函式暴露給window
window.$jsonp = jsonp;
})(window,document,undefined);
</script>
<script>
$jsonp('http://api.douban.com/v2/movie/in_theaters',{
'count':1
},function(data){
document.getElementsByTagName('body')[0].innerHTML = JSON.stringify(data);
})
</script>
</body>
</html>
歡迎大家提意見