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>