【前端】从登录框看前端
原文来自:http://www.w3cfuns.com/article-5599427-1-1.html
作者写的非常好,不管是用户体验,还是安全性,都没的说
在此我也学到了
1.fieldset的用法,legend主要是用来设置标题的。
2.密码安全性的问题:在密码后面加上时间戳
3.浏览器前进与后退:window.location.replace的用法 替换历史记录,即使用户在登陆后按后退也不会跳转到之前没登录过的页面
4.checkbox:<input type='checkbox' ><label>记住密码</label> 单击文字“记住密码”前面的checkbox可以做出相应的改变
5.ajax发送文件头的重要性: 有时候会出现后台取不到数据,是因为没写请求头的关系。
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send($.param({
"user":$("#user").val(),
"pwd":$("#pwd").val()
}));
一般浏览器不支持 GET 方式时 xhr.send 中添加参数,但是 POST 是可以,也是必须的,如果没有设置 Content-Type 的头部,数据送到后端便没办法解析成 key-value 的模式,后台(PHP)通过 $_POST 也拿不到数据。
6.数据走缓存
表单提交首选应该是 post,但是也不排除会用 get 方式提交,那么这个时候就应该考虑数据缓存了,如果请求的 url 相同,程序就会直接从浏览器的缓存中拿数据,并给出状态是 status: 200 OK(from cache),为了避免这些常识性的问题,记得在请求的参数中加点东西。如:加上时间戳 _s = (new Date*1 + Math.random*1E5)/1E5
7.渐进增强
在不支持javascript的浏览器用<noscript></noscript>代替 或者 document.write('浏览器不支持')
8.记住密码:cookie不能保存隐私信息,session当前会话完毕就会消失,怎样在下次浏览器启动后保存登录状态呢,用户在提交信息成功后,服务器给前端提供一个token,我们只需要保存token就可以了
9.用户多次提交:在发送之前获取token,只有一次有效。判断一段时间内用户发布的信息,然后去重复的
10.状态提示:根据ajax redaystate的状态(0,1,2,3,4)* 0.25来表示当前的状态条 width= (0|1|2|3|4) *0.25 %;
demo:http://qianduannotes.duapp.com/demo/login/login.html
1 /** 2 * @author Barret Lee 3 * @barret.china@gmail.com 4 */ 5 Function.prototype.bind = Function.prototype.bind || function(context){ 6 var args = Array.prototype.slice.call(arguments) 7 , self = this; 8 9 return function() { 10 return self.apply(context, args.slice(1)); 11 } 12 }; 13 14 var Tool = { 15 info: { 16 $infoBar: $(".info-bar"), 17 show: function(msg, callback){ 18 var this_ = Tool.info; 19 20 clearTimeout(this_.timer); 21 22 this_.$infoBar.show().css("right", "-255px") 23 .find("sup").on("click", function(){ 24 clearTimeout(this_.timer); 25 this_.$infoBar.fadeOut('fast'); 26 }); 27 28 this_.$infoBar.find("div").html(msg); 29 30 this_.$infoBar.animate({"right": 15}, 300, function(){ 31 this_.timer = setTimeout(function(){ 32 this_.hide(); 33 }.bind(this_), 2000); 34 }); 35 callback && callback(); 36 }, 37 hide: function(callback){ 38 Tool.info.$infoBar.fadeOut(function(){ 39 $(this).css("right", "-255px"); 40 callback && callback(); 41 }); 42 } 43 }, 44 load: function(percentage, callback){ 45 $(".loading-bar").show().find("div") 46 .animate({"width": percentage*100 + "%"}, 200, function(){ 47 percentage == 1 && 48 $(this).parent().fadeOut('100', function(){ 49 $(this).find("div").css("width", 0); 50 callback && callback(); 51 }); 52 }); 53 } 54 };
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <html lang="zh"><script id="tinyhippos-injected">if (window.top.ripple) { window.top.ripple("bootstrap").inject(window, document); }</script><head> 2 <title>login By BarretLee</title> 3 <meta charset="utf-8"> 4 <link rel="stylesheet" type="text/css" href="./css/main.css"> 5 </head> 6 7 <body> 8 <div class="acenter"> 9 <h1>登录页</h1> 10 <fieldset class="login"> 11 <legend>登录</legend> 12 <form method="POST" action="./pages/login.php" enctype="multipart/form-data"> 13 <p><label for="user">用户名:</label> <input type="text" name="user" id="user"></p> 14 <p><label for="pwd">密 码:</label> <input type="password" name="pwd" id="pwd"><a href="#" class="forget-pwd">忘记密码?</a></p> 15 <p><input type="checkbox" checked="checked" name="rem" id="rem"><label class="rem-pwd" for="rem">记住密码</label></p> 16 <p><input type="reset" value="重置"><input type="submit" value="提交"></p> 17 </form> 18 </fieldset> 19 </div> 20 21 <div class="loading-bar" style="display: none;"><div style="width: 0px;"></div></div> 22 <div class="info-bar" style="right: -255px; display: none;"><div>用户名错误!</div><sup>×</sup></div> 23 24 <script type="text/javascript" src="./js/jquery.js"></script> 25 <script type="text/javascript" src="./js/tools.js"></script> 26 <script type="text/javascript"> 27 function submitForm() { 28 var xhr 29 , url = "./pages/login.php" 30 , delta = .25; 31 32 if(window.addEventListener) xhr = new XMLHttpRequest; 33 else xhr = new ActiveXObject("Msxml2.XMLHTTP"); 34 35 xhr.open("POST", url, true); 36 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 37 xhr.onreadystatechange = function(){ 38 var res , errno , msg , noop = function(){}; 39 40 if(xhr.readyState == 4 && xhr.status == 200) { 41 res = eval('(' + xhr.responseText + ')'); 42 errno = res.errno; 43 msg = res.msg; 44 45 switch(+errno) { 46 case 0: 47 window.location.href = "./succ.php"; 48 break; 49 case 1: 50 noop = function(){ 51 $("#pwd").val(""), 52 $("#user").focus().select(); 53 }; 54 break; 55 case 2: 56 noop = function(){ 57 $("#pwd").val("").focus(); 58 }; 59 break; 60 } 61 } 62 Tool.load(delta * xhr.readyState, function(){ 63 Tool.info.show(msg, noop); 64 }); 65 }; 66 xhr.send($.param({"user":$("#user").val(),"pwd":$("#pwd").val(), "t": new Date*1})); 67 } 68 69 $(function(){ 70 $("input[type=submit]").on("click", function(evt){ 71 evt.preventDefault(); 72 if($("#user").val() == "") { 73 Tool.info.show("用户名不能为空!", function(){ 74 $("#pwd").val(""), 75 $("#user").focus().select(); 76 }); 77 return; 78 } 79 submitForm(); 80 }) 81 }); 82 </script> 83 84 </body></html>