MUI 官网:https://www.dcloud.io/mui.html
MUI 文档:https://dev.dcloud.net.cn/mui/ui/
演示地址:https://dcloud.io/hellomui/ (支持手机和电脑浏览器)
开发工具:https://www.dcloud.io/hbuilderx.html (Hbuilder X)
查看 MUI 文档,可以看到 MUI 框架已经对 ajax 请求做了封装处理,方便我们使用。具体使用方式与 jQuery 中封装的ajax类似。
下面看一下文档描述:
Ajax
mui封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型; 在 mui.ajax
方法基础上,mui 进一步简化出最常用的 mui.get
、mui.getJSON
、mui.post
三个方法。
为了在功能和性能间取得更好的平衡,mui.ajax
目前实现逻辑如下:
- App端,跨域情况下,使用
plus.net.XMLHttpRequest
- App端,WKWebview环境,使用
plus.net.XMLHttpRequest
- 其它情况,默认使用
window.XMLHttpRequest
注意:plus.net.XMLHttpRequest
必须在 plus ready
事件触发后才能使用。
为适应iOS13起苹果公司将 UIWebview
列为私有API的问题,从HBuilderX 2.2.5+版本已将iOS上默认内核由 UIWebview
调整为 WKWebview
。但WKWebview
有更严格的跨域限制,普通xhr或ajax联网会报错:Script error.filename:lineno:0
错误;此时必须使用plus.net.XMLHttpRequest
,详见:https://ask.dcloud.net.cn/article/36348,所以在 WKWebview
下,请务必在 plus ready
后再调用mui.ajax,同时注意也无法再使用浏览器的xhr及jquery的ajax。
ajax参考文档:https://dev.dcloud.net.cn/mui/ajax/
代码示例:如下为通过post方式向某服务器发送鉴权登录的代码片段
mui.ajax('http://server-name/login.php',{
data:{
username:'username',
password:'password'
},
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
headers:{'Content-Type':'application/json'},
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},
error:function(xhr,type,errorThrown){
//异常处理;
console.log(type);
}
});
mui.post()
方法是对mui.ajax()
的一个简化方法,直接使用POST请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()
方法),使用方法: mui.post(url[,data][,success][,dataType])
,如上登录鉴权代码换成mui.post()
后,代码更为简洁,如下:
mui.post('http://server-name/login.php',{
username:'username',
password:'password'
},function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},'json'
);
mui.get()
方法和mui.post()
方法类似,只不过是直接使用GET请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()
方法),使用方法: mui.get(url[,data][,success][,dataType])
,如下为获得某服务器新闻列表的代码片段,服务器以json格式返回数据列表
mui.get('http://server-name/list.php',{category:'news'},function(data){
//获得服务器响应
...
},'json'
);
如上 mui.get()
方法和如下 mui.ajax()
方法效果是一致的:
mui.ajax('http://server-name/list.php',{
data:{
category:'news'
},
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
success:function(data){
//获得服务器响应
...
}
});
mui.getJSON()
方法是在mui.get()
方法基础上的更进一步简化,限定返回json格式的数据,其它参数和mui.get()
方法一致,使用方法: mui.get(url[,data][,success])
,如上获得新闻列表的代码换成mui.getJSON()
方法后,更为简洁,如下:
mui.getJSON('http://server-name/list.php',{category:'news'},function(data){
//获得服务器响应
...
}
);
mui ajax再次封装,方便在项目中使用:
之前对 jQuery的 ajax 封装请看这篇:jQuery异步请求错误信息处理
使用 mui ajax 需要注意的问题:
1、mui组件中,发送ajax请求时,没有该功能:用户发送请求时,加载等待提示层,请求完成时自动关闭提示。所以需要自己实现 或者使用第三方js框架实现。但是在 plus (调用安卓原生内容)环境中,提供了相关 加载等待提示 api。
2、需要注意当用户 ajax 请求发送错误时,需要提示用户
改写上一篇登录逻辑 ,移动端开发框架mui之注意事项及制作登录页
编写 app.js 文件 和 添加加载图片(gif动图):
/**
* 服务器地址
* 在这里统一配置服务器地址,在正式环境中可能需要换成 外网ip 或 域名
*/
var AppPath = "http://192.168.0.100:8080/WebApi";
/**
* 用户发送请求时,加载等待提示层,请求完成时自动关闭提示
* 遮罩蒙版常用的操作包括:创建、显示、关闭,如下代码:
* var mask = mui.createMask(callback);//callback为用户点击蒙版时自动执行的回调;
* mask.show();//显示遮罩
* mask.close();//关闭遮罩
* 注意:关闭遮罩仅会关闭,不会销毁;关闭之后可以再次调用mask.show();打开遮罩;
*/
var mask = mui.createMask();//遮罩层
/**
* 加载提示内容,动态添加到网页上:水平垂直居中显示
*/
var loadHtml = "";
loadHtml += '<div class="loading" style="display: none;position:fixed;top:50%;width: 100%;text-align: -webkit-center;text-align: center;;margin-left:width/2;margin-top:height/2;">';
loadHtml += '<img style="vertical-align: middle;" src="image/loading-2.gif" /> <span style="vertical-align: middle;" class="loadingText">加载中...</span>';
loadHtml += '</div>';
document.writeln(loadHtml);
/**
* 异步公共请求方法 POST 方式
* @param {Object} url 请求地址,地址前面需要跟上/ 。例如:"/user/login"
* @param {Object} postData 请求参数。例如:{ user: "test", pass: "123", ... }
* @param {Object} loadMsg 加载提示信息,默认 "加载中..." 。
* @param {Object} success 请求成功回调函数
* @param {Object} error 请求失败回调函数
* xhr:xhr实例对象
* type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"
* errorThrown:可捕获的异常对象
*/
function ajaxJson(url , postData , success , error , loadMsg){
mui.ajax(
AppPath + url,
{
data: postData,
async: true,
dataType:'json',//服务器返回json格式数据
type:'POST',//HTTP请求类型
timeout:15000,//超时时间设置为15秒;
headers:{'Content-Type':'application/x-www-form-urlencoded'},
beforeSend: function() {
if (loadMsg && loadMsg.length > 0){
//如果传入自定义加载文字,则更新提示文字
document.querySelector(".loadingText").innerHTML = loadMsg;
}
//plus.nativeUI.showWaiting(loadMsg, {});
mask.show();//显示遮罩层
document.querySelector(".loading").style.display = "inline-block";//显示加载提示层
},
complete: function() {
//plus.nativeUI.closeWaiting();
document.querySelector(".loading").style.display = "none";//关闭加载提示层
mask.close();//关闭遮罩层
},
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
return success(data);
},
error:function(xhr,type,errorThrown){
//异常处理;type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"
var errorMsg = "很抱歉,加载数据错误";
if (type && type == "timeout"){
errorMsg = "连接服务器超时,请检查网络";
}
return error(errorMsg);
},
}
);
}
/**
* 异步公共请求方法: 文件上传
* @param {Object} url 请求地址,地址前面需要跟上/ 。例如:"/user/login"
* @param {Object} postData 请求参数。例如:{ user: "test", pass: "123", ... }
* @param {Object} loadMsg 加载提示信息,默认 "加载中..." 。
* @param {Object} success 请求成功回调函数
* @param {Object} error 请求失败回调函数
* xhr:xhr实例对象
* type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"
* errorThrown:可捕获的异常对象
*/
function ajaxUploadFile(url , postData , success , error , loadMsg){
mui.ajax(
AppPath + url,
{
data: postData,
async: true,
dataType:'json',//服务器返回json格式数据
type:'POST',//HTTP请求类型
timeout:15000,//超时时间设置为15秒;
//headers:{'Content-Type':'application/x-www-form-urlencoded'},
//文件上传会自动添加Content-Type:multipart/form-data
//headers:{'Content-Type':'multipart/form-data'},
cache: false,
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
beforeSend: function() {
if (loadMsg && loadMsg.length > 0){
//传入自定义加载问题,则更新提示文字
document.querySelector(".loadingText").innerHTML = loadMsg;
}
//plus.nativeUI.showWaiting(loadMsg, {});
mask.show();//显示遮罩层
document.querySelector(".loading").style.display = "inline-block";//显示加载提示层
},
complete: function() {
//plus.nativeUI.closeWaiting();
document.querySelector(".loading").style.display = "none";//关闭加载提示层
mask.close();//关闭遮罩层
},
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
return success(data);
},
error:function(xhr,type,errorThrown){
//异常处理;type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"
var errorMsg = "很抱歉,加载数据错误";
if (type && type == "timeout"){
errorMsg = "连接服务器超时,请检查网络";
}
return error(errorMsg);
},
}
);
}
登录示例代码:
//使用 addEventListener()方法进行事件绑定
//登录按钮
var loginBtn = document.getElementById("loginBtn");
loginBtn.addEventListener("tap" , function(){
var account = document.getElementById("account").value;
var password = document.getElementById("password").value;
if (!account){
alert("请输入账号");
}else if(!password){
alert("请输入密码");
}else if(account != "admin" || password != "123456"){
alert("账号或密码错误");
}else{
//执行登录逻辑
var postData = {
account: account,
password: password
}
ajaxJson(
'/userInfo/login',
postData,
function(resultObject){
//请求成功处理
if (resultObject.code == 1000){
//var loginObject = resultObject.data;
//登录成功
alert("恭喜您。登录成功");
}else{
alert(resultObject.msg);
return;
}
},
function(errorMsg){
//请求失败处理
alert(errorMsg);
},
"登录中..."
);
}
});
登录效果截图:(由于这边没有发布后台登录接口,所有会提示超时错误)
登录页及实现源码:
链接:https://pan.baidu.com/s/11lpkRjhqadNLCrN1vTn2xA
提取码:j9za
文件上传示例代码:
/**
* 文件上传逻辑
*/
function uploadFile(formData){
//var form = new FormData(); // FormData 对象
//指定上传文件域,相当于页面表单文件域的name参数值(对应于后台定义的File对象))
//form.append("file", fileObj); // 文件对象
ajaxUploadFile(
'/fileUpload/upload',
formData,
function(resultObject){
//请求成功处理
if (resultObject.code == 1000){
alert("恭喜您。文件上传成功");
var fileUrl = AppPath + resultObject.data;
//console.log("fileUrl = " + fileUrl);
}
else{
alert(resultObject.msg);
}
},
function(errorMsg){
//请求失败处理
alert(errorMsg);
},
"文件上传中..."
);
}
文件上传参考:
HTML5 AJAX 异步上传文件
struts2异步上传文件及前后端图片压缩上传