686
社区成员




这个作业属于哪个课程 | 2023年福大-软件工程实践-W班 |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
这个作业的目标 | 技术博客 |
其他参考文献 | ajax的traditional属性的作用 |
jQuery的Ajax技术是用于在不刷新整个页面的情况下,通过异步请求从服务器获取数据并更新页面的技术。在需要动态更新页面内容的情况下,可以使用Ajax技术。学习该技术的原因是为了提高网站的用户体验和性能。Ajax技术的难点在于需要处理异步请求和响应的过程,以及如何处理请求失败和超时等异常情况。
jQuery的Ajax技术是一种用于在不刷新整个页面的情况下,通过异步请求从服务器获取数据并更新页面的技术。它可以通过jQuery的$.ajax()
方法或$.get()
、$.post()
等简化方法来实现。使用Ajax技术可以提高网站的用户体验和性能,因为它可以在不刷新整个页面的情况下,动态地更新页面内容,从而避免了页面的重载和重新渲染。Ajax技术的难点在于需要处理异步请求和响应的过程,以及如何处理请求失败和超时等异常情况。为了更好地使用Ajax技术,我们需要掌握jQuery的Ajax方法的使用,了解Ajax请求和响应的过程,以及如何处理异常情况。
$.ajax({
type : "post",//传参方式
url : "接口地址",
data:{
"参数1":value1,
"参数2":value2
},
async : true,//异步|同步
traditional:true,//参数解析方式
dataType : "json",//数据类型
timeout : 1000,//超时时间(毫秒)
success : function(result){
//成功回调,返回内容为result
},
error : function(result){
//失败回调,返回内容为result
}
});
其中
traditional
参数,默认false的时候如果是{a:{b:'value'}}
是处理成a[b]
,这样形式,如果是数组:data:{a:[1,2]}
,是解析成a[]=1&a[]=2
,这种方式后台确实要做兼容(取a[b]
或a[]
)来取值。
在数组情况下把traditional
参数设置成true
,是解析成a=1&a=2
,对后台直接通过a拿数据。但是实验了下object情况,把traditional
设置成true
,转成了a=[object+Object]
,这样就是费的了。false
时解析成上面的形式应该就是类型指示作用,我看到这种格式就知道请求数据是Array还是object了,true
就是按照form提交的方式传值。
$.ajax({
type : "post",//传参方式
url : "http://test.test?act=login",
data:{
"参数1":value1,
"参数2":value2
},
async : true,//异步|同步
traditional:true,//参数解析方式
dataType : "json",//数据类型
timeout : 1000,//超时时间(毫秒)
success : function(result){
//成功回调,返回内容为result
},
error : function(result){
//失败回调,返回内容为result
}
});
这样做可以灵活定义接口的用途,比如例子中就定义了接口是用于登录用的,那么后端就需要以GET方式接收act这个参数,然后通过switch进行选择对应的接口处理部分进行处理。
当然也可以在data中进行定义。
比如:
$.ajax({
type : "post",
url : "<?=$api_link[$page_name]; ?>",
data:{
"act":"login",
"username":data.username,
"password":data.password,
},
async : true,
traditional:true,
dataType : "json",
timeout : (5000),
success : function(result){
if (result.code == 200) {
//将账号密码保存到本地
localStorage.setItem("username",data.username);
localStorage.setItem("password",data.password);
layer.msg(result.msg, function () {
window.location = 'index.php';
});
}
else {
layer.msg(result.msg);
}
},
error : function(result){
layer.msg("接口失败",{icon: 2});
}
});
针对这个问题一开始是通过外部设置一个时间控制器来实现,但是后来查阅资料发现,JQ的AJAX是支持超时的功能的,所以可以将ajax调用封装为一个函数。
//count:{test:最大次数,now:当前第几次}
var ajaxLogin = function(timeout, count, param, url){
$.ajax({
type : "post",//传参方式
url : url,
data:param,
async : true,//异步|同步
traditional:true,//参数解析方式
dataType : "json",//数据类型
timeout : timeout,//超时时间(毫秒)
success : function(result){
//成功回调,返回内容为result
},
error : function(result){
//失败回调,返回内容为result
//失败重复调用
if(count.test>count.now){
ajaxLogin (timeout, {test:count.test,now:(count.now+1)}, param, url);
}
}
});
}
根据分析有些请求极有可能是因为服务端查询速度慢,或者数据量过大造成的不能及时响应,针对这个问题,如果返回的内容本身就很多,那么无论调用多少次依然都是失败的,所以可以模仿计算机网络中的窗口进行动态的调控超时的时间,类似TTL。
//count:{test:最大次数,now:当前第几次}
var ajaxLogin = function(timeout, count, param, url){
$.ajax({
type : "post",//传参方式
url : url,
data:param,
async : true,//异步|同步
traditional:true,//参数解析方式
dataType : "json",//数据类型
timeout : timeout,//超时时间(毫秒)
success : function(result){
//成功回调,返回内容为result
},
error : function(result){
//失败回调,返回内容为result
//失败重复调用
if(count.test>count.now){
//动态增大超时数
ajaxLogin (timeout + 1000, {test:count.test,now:(count.now+1)}, param, url);
}
}
});
}
由于开发的后端是PHP,前端部分也涉及到部分PHP的脚本,在PHP脚本的插入上遇到了问题。根据分析发现是参数类型的不匹配。
比如PHP部分有:
<?php
$act = "login";
?>
而JS部分需要实现:
if(PHP的act参数 == "login"){//code}
如果这样使用就会出现失败的问题:
if(<?=$act; ?> == "login"){//code}
乍一看,感觉是利用PHP输出了一个字符串可以与字符串进行比较,但是实际会提示login未定义,因为这句语句相当于if(login == "login"){//code}
解决方法:其实解决也比较简单就是在PHP脚本外在包括一层括号,这样就可以解决问题了。
if("<?=$act; ?>" == "login"){//code}
在回调函数中可以对DOM树进行更新,可以调用jq的方法去控制页面的元素内容,可以将获取的数据通过模板动态的渲染到页面上。
比如:
$.ajax({
type : "post",//传参方式
url : "<?=$api_link[$page_name]; ?>",//接口地址
data:{
"act":"user_get",
"user":loading_user,
},
async : true,
traditional:true,
dataType : "json",
//最大等待时间
timeout : 5000,
//result.data是字符串(“编辑修改成功”或者是“编辑修改失败”)
success : function(result){
var temp_id_name = ['uid', 'nickname', 'wx_openid', 'avatar', 'invitedby', 'invitecode', 'reg_time', 'login_time', 'state'];
var lock_input = ['nickname', 'wx_openid', 'avatar', 'invitedby', 'state'];
var lock_input_holdtip = ['请输入用户昵称', '请输入微信ID', '请输入头像地址', '请输入邀请该用户的用户ID', '请输入用户状态'];
switch(result.code){
case(201):{
for(var i = 0; i < lock_input.length; i++){
var varname = "user_info_" + lock_input[i];
$("#" + varname).attr("disabled", "disabled");
$("#" + varname).attr("placeholder", "请输入用户ID");
$("#" + varname).addClass("layui-bg-gray");
}
for(var i = 0; i < temp_id_name.length; i++){
if(temp_id_name[i] != 'uid'){
var varname = "user_info_" + temp_id_name[i];
eval("$('#" + varname + "').val('')");
var form = layui.form;
form.render("select");
}
}
var form = layui.form;
form.render("select");
uid_tip = layer.tips('ID为'+loading_user+'的用户不存在', '#user_info_uid', {
tips: [1, '#3595CC'],
time: 4000
});
$("#user_info_submit").addClass("layui-btn-disabled");
break;
}
case(200):{
get_invitedby(result.data.uid);
for(var i = 0; i < temp_id_name.length; i++){
var varname = "user_info_" + temp_id_name[i];
eval("$('#" + varname + "').val(result.data." + temp_id_name[i] + ")");
}
for(var i = 0; i < lock_input.length; i++){
var varname = "user_info_" + lock_input[i];
$("#" + varname).removeAttr("disabled");
$("#" + varname).attr("placeholder", lock_input_holdtip[i]);
$("#" + varname).removeClass("layui-bg-gray");
}
var form = layui.form;
form.render("select");
$("#user_info_submit").removeClass("layui-btn-disabled").addClass("layui-btn-normal");
if(typeof uid_tip != "undefined"){
layer.close(uid_tip);
}
break;
}
case(-200):{
for(var i = 0; i < temp_id_name.length; i++){
if(temp_id_name[i] != 'uid'){
var varname = "user_info_" + temp_id_name[i];
eval("$('#" + varname + "').val('')");
}
}
var form = layui.form;
form.render("select");
for(var i = 0; i < lock_input.length; i++){
var varname = "user_info_" + lock_input[i];
$("#" + varname).attr("disabled", "disabled");
$("#" + varname).attr("placeholder", "请输入用户ID");
$("#" + varname).addClass("layui-bg-gray");
}
$("#user_info_submit").addClass("layui-btn-disabled");
layer.msg('查询失败', {icon: 2});
break;
}
default:{
break;
}
}
layer.close(index_find_user);
},
error : function(result){
//接口失败回调
layer.msg("接口失败",{icon: 2});
layer.close(index_find_user);
}
});
AJAX使用起来也比较的方便,但是细节方面还是需要注意,往往接口调用不成功就是因为一些格式的问题和符号的错误。而这些错误恰恰是开发者们容易忽视的错误,所以不用专门的调试工具仅仅靠浏览器的调试可能很难发现这些问题。在我的实际开发中也经常遇到这些问题,特做此篇分享参考。