Ajax學習第六天
Ajax學習第六天——JSONP代碼優化,使用最初版本的JSONP代碼,即昨天博客上寫的步驟,會有以下3個問題:
- 使用JSONP方法時,每次都要將函數名稱發送給服務器端,一旦服務器端程序員修改函數名,前端界面也要一起修改,造成了溝通成本的增加;
- 一旦出現有多個請求時,採用此時的JSONP代碼會出現若第一個請求還未執行完成,發送第二個請求,服務器端會覆蓋第一次請求的結果,導致第一次的請求結果被覆蓋;
- 若多次調用JSONP,要重複編寫大量相似且冗餘的代碼,比較繁瑣。
針對以上3個問題,提出以下3個要求:
- 無論怎麼修改函數名,都不需要前端後端程序員重新溝通;
- 將script的請求的發送變成動態請求;
- 封裝JSONP函數,方便請求發送。
實現以上三個要求的代碼如下(本代碼針對前端,服務器端代碼未貼出):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">點我發送請求</button>
<script>
//獲取按鈕標籤
var btn = document.getElementById('btn');
//爲按鈕添加點擊事件
btn.onclick = function () {
jsonp({
url: 'http://localhost/jsonp',
data: {
name: 'zs',
age: 20
},
success: function (data) {
console.log(data);
}
});
}
function jsonp(options) {
//動態添加script標籤 使發送請求這一動作變得可控,否則頁面一上來就會被加載
var script = document.createElement('script');
//拼接字符串的變量
var params = '';
//遍歷拿到數據
for (attr in options.data) {
params += '&' + attr + '=' + options.data[attr];
}
//函數名隨機 否則如果有兩個按鈕同時點擊響應同一個函數的話,後面函數返回結果會覆蓋前面函數的返回結果
var attrName = 'script' + Math.random().toString().replace('.', '');
//它已經不是一個全局函數了
///我們要想辦法讓它重新變爲全局函數 .後面不能是個變量哦!
window[attrName] = options.success;
//設置script標籤的src屬性
script.src = options.url + '?callback=' + attrName + params;
//動態添加script標籤
document.body.appendChild(script);
//爲script標籤添加onload事件 此事件是頁面全部加載完畢後才觸發
script.onload = function () {
//頁面加載完畢後移除script標籤,因爲執行完畢後此標籤已沒有意義
document.body.removeChild(script);
}
}
</script>
</body>
</html>