mui ajax交互 php,HBuilder+MUI编写一个登录页面(Ajax交互)

登录页面

那我们先构思一下登录页面都需要什么内容:用户名,密码,登录按钮。如果你有一个得力的美工,我们还可以加上酷炫的美工设计。

HBuilder提供一组UI组件,请参看这里:MUI。

对于一个熟悉web开发的人来说,上面的这些都太简单了,分分钟就可以搞定了。但是别忘了这是移动开发,与普通的浏览器应用还是有所不同。接下来我们来看看页面的布局应该怎么设计。

这里大家不要忘记一个原则,因为目前HTML5+ 的实现仅此一家(HBuilder),所以我们在实现各种功能的时候,一定要遵循HBuilder官方推荐的方法。

接下来我们从一个index.html开始。

HBuilder默认生成的index.html里的meta部分,只有viewport一个属性:

Html代码

其次,我们要引入 mui 需要的 css,以及相应的 javascript 文件。

Html代码

如果你想问如果不用 mui 和默认的 app.js 可以吗?答案是肯定的。但是,你可能会遇到很多意想不到的问题。所以,对于一个界面组件 mui 来说,个人如果你有强大的美工小伙伴,那么不用 mui 是完全可以的。但是 app.js ,还是最好用吧!

另外,按照官方的说法,尽量不要用 jquery等 js 类库,这会严重影响你的应用的速度。所以,请遵循官方的建议。其实在移动端现代浏览器上, jquery 也真的是可有可无了。

至此,HTML 的 head 部分就结束了。接着我们开始写body部分了。

按照官方的说法,页面中所有的内容都应该放入一个 div 中,并且这个 div 的class 应该是 "mui-content" --- 当然,这是你使用 mui 的时候。这里我们暂定会使用 mui 。

按照一般的方式,我们都会在窗口的底部加一个 copyright 之类的文字。按照标准的说法,我们需要有一个class="mui-bar mui-bar-tab" 的 div,而且要注意:这个 mui-bar DIV 一定要放到 mui-content 之上。总之,最后的代码应该是这个样子:

Html代码

这是底部信息

上面的 mui-bar 里,又额外加了一些样式,用于控制高度,大家可以根据需要自行订制。

接下来,我们来放入一些 mui 的组件:输入框

Html代码

用户名

密码

登录

  注册

这里的输入框和button 按钮都是 mui 提供的组件。我使用了一些 margin 等属性控制了一下位置。个人觉得,输入框组件还好,按钮组件的样式就比较一般了。如果你有好的美工,还是自己打造好看的按钮比较好。

在 html 对象的命名上,也秉承了一贯的原则,用唯一的ID 来标示一个对象。总之,这个内容对于有web开发经验的人来说,没有什么特别的地方。

至于你想让输入框垂直居中,请自行查找“如何让 div 垂直居中”,解决方案是一样的。

接下来就是重头戏了,登录按钮如何与服务器进行交互?按照web开发的理解,有这么几种选择:

定义一个表单(form),点击登录按钮的时候提交到后台。后台处理完毕后,显示新的页面给前端。

在登录按钮上绑定一个click方法。点击的时候,使用Ajax发送数据到后台,接受到数据后,前端页面更新。

对于一个手机应用,如果出现页面刷新,或者大白页这样的状态肯定是不好的体验。所以,在手机的HTML5开发中,我们绝对不会使用 form 提交这样的东西的。可以肯定的说:我们只用 Ajax。

按照官方的说法,尽量不要使用JQuery,同时,也不要使用 onclick 这样的方式,取而代之应该使用的是绑定一个事件:

Js代码

document.getElementById("loginBtn").addEventListener('tap', function(){

处理内容;当然肯定是ajax 了。

});

这个事件的名字叫 ”tap“,也就是点击屏幕的事件。

那好学的同学肯定会问有多少个事件可以用啊?请参看这里:手势事件。这是mui 提供的一个特性--- 就这个特性来说,你很难不用 mui 这个组件,毕竟你自己再实现一个的话,又要费不少事。

那我们把这个事件的代码写在哪里好呢?最开始,还是最后边?都不是。

按照官方的说法,我们应该写在 mui 组件和页面组件全部加载完毕后 ---  就如同 JQuery一样,mui 也有一个 ready 的方法:

Js代码

mui.init();

mui.plusReady(

function() {

这里写上刚才的事件绑定方法。

}

);

到了这里,画面的部分基本完事了,整个代码大概是这个样子:

Html代码

测试

这是底部信息

用户名

密码

登录

  注册

mui.init();

mui.plusReady(

function() {

document.getElementById("loginBtn").addEventListener('tap', function(){

alert("点击了登录按钮");

});

}

);

这时,你可以把手机连接到电脑上,然后进行调试,就可以看到第一个登录的画面了。点击登录按钮,会弹出”点击了登录按钮“这个对话框。

对于mui,虽然你可以不使用mui 组件,但是一些基本的规则,例如 mui.init,mui.plusReady 这样的方法,还是要使用的。

另外,mui 的布局方案中没有垂直居中的方式(希望以后能增加上),虽然方式有很多,但是仍然推荐这个:CSS Transform让百分比宽高布局元素水平垂直居中

接下来,我们就要实现登录按钮通过ajax与后台进行交互。

Ajax交互

接下来我们该完成客户端与服务器的交互的部分了,这种交互我们使用的是AJAX方式,页面不会因为刷新而现实大白页。

交互这部分可以分成两个部分:服务器端和客户端。

服务端以Java语言为例子(因为我只做过Java的)。其实 c#或者php等语言实现起来也都是基本一样的,可以当做参考。

如果你正在使用SpringMVC,那么就简单了,因为Spring已经封装了Ajax的调用方式。如果像我一样,没有使用SpringMVC,那么很遗憾,你需要一个能够解析json的库。经过比较,我选择了 jackson 这个工具。注意:在写这个文章的时间点,在网上搜索的jackson网站已经迁移到了github,所以,请使用本文提供的新的链接。

下面的例子也是基于jackson解析的。如果你使用了SpringMVC,或者其他解析json的工具,或者其他语言如PHP,应该也是差不多的。

下面来看一下一个登录过程的流程:

9144ecfdd75dcf2332d4f3193a312e43.png

流程虽然比较多,但是很容易理解。先从客户端看起。

首先就是通过Ajax的方式,将用户名和密码发送给客户端。为了安全,我们不能直接发送明文的密码,必须将密码加密。可选择的方式很多,一般都是不可逆的hash方式,如md5, sha1的方式加密。在本例中我们选择 md5的方式加密。javascript里的md5现成的方法很多,大家自己寻找一个合适的吧。但是标准就是:小,快,使用简单。

接下来就是ajax的使用。mui 提供了ajax的使用方法,请参看这里。 不过如果你按照文档那样,每个ajax调用都写那么一堆代码,一会你的代码就会臃肿不堪。所以,我对ajax调用又做了一个简单的封装,避免每次都设置相同的参数:

Js代码

function postData(url, data, callback, waitingDialog) {

mui.ajax(url,{

data:'data='+JSON.stringify(data),

dataType:'json',

type:'post',

contentType:"application/x-www-form-urlencoded; charset=utf-8",

timeout:60000,

success:callback,

error:function(xhr,type,errorThrown){

waitingDialog.close();

mui.alert("", "错误", "OK", null);

}

});

}

data 属性:就是要传递给服务端的数据。之所以要加上 'data=' 这个东西,就是为了让服务器端知道变量的名字是 "data" 。而传递的json 数据,也必须通过JSON.stringify方式转换成字符串。

contentType属性:这个很重要。如果没有这个,你在后台得到的中文字符串就会是乱码。其实如果你熟悉Jquery,对这个属性应该不会陌生。

error属性:出错的处理。这里的 waitingDialog 是一个等待的对话框。在点击登录按钮后,会显示一个等待的对话框。无论出错了,还是正常处理了,都必须要关闭这个等待的对话框。同时用 mui.alert 显示了一个错误的消息。

以上就是 ajax 的请求函数。

接下来看看登录按钮的处理:

Js代码

// 登录处理,还记得我们上一篇写得的按钮关联的事件吧

document.getElementById("loginBtn").addEventListener('tap', function(){

// 显示一个等待的对话框

var wd = plus.nativeUI.showWaiting();

// 构造要传递的json数据

// $id 是一个通过 id 取得对象的方法,

// 内容就是 return document.getElementById();

var data = {"userName": $id('username').value,

"userPassword":md5Hash($id('userpassword').value)

};

// 调用ajax

postData(SERVER_HOST + MODULE_LOGIN, //服务端的URL

data,// json 数据

function(data) {

wd.close(); // 调用成功,先关闭等待的对话框

if(data.result != "checkOK") {

// 如果密码错误,提示一下信息

mui.alert("用户名或密码错误", "登录错误", "关闭");

return;

}

// 保存token,以便于下次自动登录

localStorage.setItem(TOKEN_USER, $id('username').value);

localStorage.setItem(TOKEN_LOGIN, data.token);

// 清空用户名,密码

$id('username').value = "";

$id("userpassword").value = "";

// 打开下一个画面

mui.openWindow(

{

url:'mainShow.html',

id:'mainShow',

}

);

},

wd//传递给postData的最后一个参数,失败的时候关闭等待对话框

);

});

上面的代码都有注释,但是有的地方还是说明一下。

plus.nativeUI.showWaiting(); 这是一个原生的调用,并非用 div 来模拟对话框。这也是HBuilder的强力武器之一:Native.js。Native.js的概念,在第一篇入门文章里有介绍。具体的API用法,请参照官方的文档,里边有一个 Native.js 的部分。

传递给服务器端的数据的部分,正如流程里所示,对密码进行了加密。对于 ajax 的调用,使用了之前封装的 postData 方法。

返回值是一个 json 对象,变量名字为 data。如果 data.result 不等于 "checkOK" ,那么就认为密码错误,提示错误信息。

注意:在实际的应用中,判断返回数据的有效性,最好不使用字符串,而是使用数字。如 1表示密码错误,0表示校验通过。并且,对于返回值的格式,最好有统一的格式定义。之前我为了尽快完成功能,只是随意地使用了各种字符串,各种变量来处理返回的状态,等到程序大到一定程度的时候,就发现这很混乱,不容易维护了。

保存 token ,是为了下次打开程序的时候能自动登录,无需再次输入用户名和密码。

之后,有一个清除用户名和密码的操作。为什么需要这个操作?在 webview 的理解这篇文章说过,页面的webview 创建完毕后,是不会自己销毁的。虽然你后面可以再次迁移到别的webview,但是新的webview也只是覆盖在了之前的webview上。当我们的程序有注销的功能的时候,需要再次显示登录画面。如果登录画面没有经过 销毁-> 再构建的过程,那么显示登录画面的时候,就会显示出来你上次输入的用户名和密码。所以,我们在这里手动清空一下。

之后,使用 mui.openWindow 打开下一个页面。

接下来是服务器端的部分。在ajax中,我们给服务器端传递的参数名字叫 data,那么无论你是使用java也好,还是php 也好,都需要从 request 中取出 "data" 这个变量。这个变量的值就是字符串化的json。

本例使用的 jackson 来解析 json 数据,代码很简单:

Java代码

ObjectMapper mapper = new ObjectMapper();

UserData userData = mapper.readValue(data, UserData.class);

UserData就是一个定义了用户名和密码变量的class,没有任何的逻辑。(按照Domain Driven Desgin的概念,它就是一个值对象,而不是实体,此乃题外话)

接下来就是查询数据库,验证用户名,密码是否有效。如果有效的话,我们要创建一个token返回给前台。为了保持唯一性,这个token 最好是和用户名相关联的。简单点的方法:md5(用户名+系统时间+随机数)。而且我们要把这个token保存在数据库里。为了安全,可以设置一个有效期。

处理完毕后,使用 jackson 构造json数据,返回就可以了,简单的例子:

Java代码

response.setContentType("application/json");

response.setCharacterEncoding("UTF-8");

try {

response.getWriter().print(json);

response.getWriter().flush();

response.getWriter().close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

这样,登录的客户端和服务器端的部分就完成了。

当用户再次打开应用的时候,先判断localstorage 里是否保存有 token。如果有 token ,那么就通过ajax发送给服务器,服务器判断token 的有效性,如果验证通过,那么自动登录就成功,否则失败。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值