需求
登录的时候,如果填写了错误信息,也会直接提交到验证页面,但是是验证错误。虽然写了自动跳转回登录页面的函数,但是还是感觉用户体验不佳,所以要求在一个页面完成登录和验证功能。另外除了登录之外,应该写到留言板的大概结构了。
分析
1.同一个页面验证问题,因为这个涉及到了后台数据库,所以决定用ajax来实现异步验证。虽然Jqery是比较好用,但是为了练习,还是放弃了使用,以后会用这个库来替换他。
2.留言板的主体结构,我觉的应该写成类似于百度贴吧的形式。
实现
因为之前都是写接口的,所以是没有接触过AJAX,在W3C里面看了看,觉的还是蛮简单的。就是创建XMLHttpRequert对象,当然IE另算(我都想放弃使用这个浏览器的用户了!!!)。然后大概有几个方法,涉及到HTTP协议的几个参数,总体来说还是挺简单的。后台脚本,就是把之前的验证脚本再改一改就可以直接用了。废话不多,上代码。
<?php
session_start();
if(!empty($_POST['usr']) && !empty($_POST['pwd']) && !empty($_POST['captcha'])){
if(strcasecmp($_POST['captcha'],$_SESSION['captcha']) <> 0){
echo '验证码不正确';
exit();
}
$con = new mysqli();
$con->connect('localhost','root','123456','learn');
$usr = $con->query("select pwd from user where username = '".$_POST['usr']."'");
$usr = $usr->fetch_array();
if(md5($_POST['pwd']) <> $usr['pwd']){
echo '用户名密码不正确,请重试';
exit();
}
}else{
echo "请填写完整信息!";
}
?>
以上就是ajax调用页面的代码。
点击登录,在本页面实现提醒的功能也是费了一些功夫的。主要的难点在于,我在submit之前,先用了onsubmit来判断是否为空,然后阻止提交。本来的思路是,如果ajax验证出现了错误,就直接在函数里返回一个false,这样就可以阻止提交了。但是想象和现实还有有很大差距的,主要的原因是ajax的onreadystatechange方法是一个监听的方法,有一个readyState属性和statue属性来判断调用返回的状态。这样的话我没有办法在写的函数里返回信息。我曾经尝试过写一个死循环来实现我的想法,但是结果是,这个例子告诉我,永远不要尝试用死循环来解决问题。所以还希望有知道的牛人能告诉我怎么用我这个想法来实现我这个想法。
因此我用了另一种方法,把submit这个属性的按钮去掉,换成了一个button控件,然后直接让这个控件调用判断ajax验证方法。ajax方法里面有个地方需要注意,就是一定要设置http协议的头是表单提交,要不PHP里面的$_GET方法会解析不了。这样就延伸出来一个问题,我们写接口的时候,就可以直接不要这个HTTP头,然后用加密的字符串。在服务器端就可以用file_get_content(php://input)来接受客户端发来的数据,再进行解析,可以加密,这样就可以不用HTTPS也可以进行简单的加密了。ajax验证方法函数如下。
function validation(){
var ajax;
if( window.XMLHttpRequest){
ajax = new XMLHttpRequest();
} else {
ajax = new ActiveXObject("Mircosoft.XMLHTTP");
}
var postBody;
postBody = "usr="+document.getElementById('username').value+"&pwd="+document.getElementById('pwd').value+"&captcha="+document.getElementById('captcha').value;
ajax.open("POST","login_validation.php",true);
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajax.send(postBody);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
if(ajax.responseText == ""){
document.getElementById("login_content").submit();
}else{
document.getElementById('warning').innerHTML = "<td colspan= '3'>"+ajax.responseText+"</td>";
document.getElementById('login_form').style.height = "280px";
document.getElementById('warning').style.color = "red";
}
}
}
}
上面代码,如果验证未成功,就增加一行表格,然后提示出错。同时也调整了表格的高度。如果验证成功就直接提交到登录后的界面。
剩下的问题就是搭一个简单的后台,目前做到了,显示文章列表和显示文章内容。这块没有什么难点。主要的就是,因为涉及到了中文内容,所以出现了让人头疼的字符问题,我看了一下,之前设置的GBK格式真是验证的有欠考虑,所以改用UTF-8格式,把所有的文件编码都改成了utf8,把数据库也改成了utf8。在网页中加上<meta charset = "utf8">。这样在网页中就会用UTF-8的编码格式,来显示网页。但是万万没有想到,结果还是出错了。主要出现在数据库中,我把所有的数据库设置都设置成了utf8,但是依然没有效果。网上看了一下,果断用set names = "utf8",解决了这个问题。然后文章都设置好了超链接,主要是用get方法来传递文章的数据,然后来显示文章。我觉的后期应该写一个mysqli的继承类来方便操作,或者用PDO来防止SQL注入,但是这是以后的问题了,这个东西就慢慢改进了~!下面上代码
<html>
<head>
<meta charset = "utf-8">
<style type = "text/css">
*{
margin:0;
padding:0;
}
#main{
margin:50px auto;
width:80%;
}
#main table{
width:70%;
margin-left:100px;
padding:10px;
}
#title1{
width:%40;
}
#title2{
width:20%;
}
#title3{
width:20%;
}
#main table tr{
text-align:center;
padding:10px;
}
#main table td{
padding:10px;
}
</style>
</head>
<body>
<div id = "main">
<table>
<tr>
<th id = "title1">
主题
</th>
<th id = "title2">
作者
</th>
<th id = "title3">
创建时间
</th>
</tr>
<?php
$con = new mysqli();
$con->connect('localhost','root','123456','learn');
$con->query('set names "utf8"');//解决了编码的问题
$sql = $con->query('select posts.id,posts.user_id,user.username,posts.title,posts.create_time from posts,user where user.id = posts.user_id');
while($s = $sql->fetch_assoc()){
echo '<tr>
<td>
<a href = "post.php?post_id='.$s['id'].'&author='.$s['user_id'].'" >'.$s['title'].'</a>
</td>
<td>
'.$s['username'].'
</td>
<td>
'.date('y年m月d日,h:i:s',$s['create_time']).'
</td>
</tr>';
}
?>
<table>
</div>
</body>
</html>
上面这个是文章列表的代码
<?php
if(isset($_GET['post_id']) && isset($_GET['author'])){
$post_id = $_GET['post_id'];
$author = $_GET['author'];
$con = new mysqli();
$con->connect('localhost','root','123456','learn');
$con->query('set names "utf8"');
$sql = $con->query("select title,content from posts where id = ".$post_id." and user_id = ".$author);
$post = $sql->fetch_array();
if(empty($post['title']) || empty($post['content'])){
echo '<meta charset = "utf8">没有这个文章';
exit();
}
}else{
echo '<meta charset = "utf8">文章不存在';
exit;
}
?>
<html>
<head>
<meta charset = "utf-8">
<style>
*{
padding:0;
margin:0;
}
#post{
margin:20px auto;
width:80%;
}
#title{
text-align:center;
margin-botton:20px;
}
#content{
margin:15px auto;
width:60%;
line-height:24px;
}
</style>
</head>
<body>
<div id = "post">
<div id = "title">
<h2><?php echo $post['title'] ?></h2>
</div>
<div id = "content">
<?php echo $post['content'] ?>
</div>
</div>
</body>
</html>
上面这个是显示文章内容的代码。
顺带把关于文章的SQL写在下面
CREATE TABLE IF NOT EXISTS `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`title` varchar(256) NOT NULL COMMENT '帖子主题',
`content` longtext NOT NULL COMMENT '帖子内容',
`user_id` int(11) NOT NULL COMMENT '所属用户ID',
`create_time` int(11) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
)
这样就基本完成了一个简单看的内容,下面还没有做添加文章,删除文章和查找文章的功能。
总结
经过这两天的学习,感觉又提升了一些能力,从一些简单的问题,引申到了工作中一些实际的问题,感觉这样的确能有挺大的提高!