简单介绍注册和登录功能的实现

  这段时间正好做有关的网页注册登录功能,想了想还是写一篇博客记录一下功能实现的流程,方便以后查阅。
  我先把注册和登录的各种操作与判断流程分别说一下,方便理解。

注册
  • 注册页面最重要的四部分是注册邮箱、密码、确认密码与注册按钮 。用户分别输入邮箱、密码与确认密码后点击注册按钮完成注册。
  • 前端部分要做的事主要是判断用户是否在以上三个部分输入了信息,接着判断邮箱的格式是否正确(前端也可不进行判断邮箱的格式,因为后端服务器也会判断一次)、密码与确认密码两个部分的内容是否相同。
  • 当用户内容输入正确后,客户端会将用户所输入的内容传给服务器。服务器得到信息后会再一次判断信息的格式等是否符合要求,无误后将得到的信息与数据库中的信息作比较,如有重复则提示前端邮箱已被注册,无重复则将信息存入数据库并提示前端注册成功。
注册部分前端代码

前端html部分主要是在form表单加input标签,利用form标签来提交HTTP请求。

<form id="formSignUp">
  <div>
    <label for="email">邮箱</label>
    <input type="text" name="email" id="email">
    <span class="error"></span>  
  </div>
  <input type="submit" value="注册">
</form>
注册页面样式

前端JS部分代码主要是判断用户是否有输入内容、输入内容格式是否正确。

// 以下JS代码引用JQuery库,使用JQuery语法
let $form = $('#formSignUp')
let hash = {} // 声明一个空对象
$form.on('submit', (e)=>{ // 监听submit事件
  e.preventDefault()  // 取消默认事件
  $form.find('.error').each((index, error)=>{ // 清空所有具有error属性的span标签的文本内容
    $(error).text('')
  })
  let list = ['email'] 
  list.forEach((name)=>{ // 遍历list数组
    let value = $form.find(`[name="${name}"]`).val() // 取得用户所输入的内容
    hash[name] = value // 将用户输入的内容存入空对象中,如: {email: '374xxxxxx@qq.com'}
  })
  if(hash.email === ''){ // 判断用户是否有输入
    $form.find('#email').siblings('.error').text('请输入邮箱') // 如果用户每天输入信息,则在span标签中写入'请输入邮箱'
    return 
  }
  // 使用JQuery中AJAX的API,以下是Ajax函数的简写形式
  $.post('/sign_up', hash) //使用HTTP POST请求,请求路径'/sign_up',并发送给服务器一个对象
    then((response)=>{ // 请求成功
      alert('注册成功')
      window.location.href = '/sign_in' // 跳转到新的路径
    },(request)=>{ // 请求失败
      let {errors} = request.responseJSON // 使用ES6语法解析赋值,取得服务器返回的内容
      if(errors.email && errors.email === 'invalid'){ // 判断服务器返回的内容
        $form.find('#email').siblings('.error').text('邮箱格式错误')
      }else if(errors.email && errors.email === 'used'){
        $form.find('#email').siblings('.error').text('该邮箱已被使用')
      }
    })
})
用户未输入信息就点击注册

用户输入邮箱格式错误
注册部分后端代码

  后端简易服务器使用nodejs搭建,如何搭建不是这篇博客主要讨论的,这里只介绍提取用户信息、判断用户信息与简单的存储数据的代码。(主要我也不太懂 - -)
  下面这段代码是用来让服务器提取客户端POST请求的第四部分内容(请求体),这是我在Stack Overflow上面找到的。这么写的主要原因是请求的第四部分不是一次性上传完毕的,它是服务器一段一段的获取到的。在服务器将所有请求体都获取到并放入body数组中之后,body = Buffer.concat(body).toString()这段代码就可以用字符串形式展示所有的请求体。

let body = []
request.on('data', (chunk) => {
  body.push(chunk)
}).on('end', () => {
  body = Buffer.concat(body).toString()
  console.log(body)
})

  下面这段代码就是分解请求体,从请求体中获取数据。比如请求体为'email=1&password=1&password_confirmation=1'

let hash = {} // 声明一个对象
body.split('&').forEach((part) => {
// 将字符串形式的请求体以'&'为界分割,转成一个数组并遍历这个数组。
//例如:['email=1','password=1','password_confirmation=1']
  let parts = part.split('=') // 操作同上,例如:['email', '1']
  let key = parts[0]
  let value = parts[1]
  hash[key] = decodeURIComponent(value) 
// 例如{email: '1'}, decodeURIComponent() 这个api是对编码后的URI字符进行解码
})
let { email, password, password_confirmation } = hash

  以下代码是用以判断服务端接受的数据email格式正确与否。

if (email.indexOf('@') === -1) { // 判断email是否含有@这个字符
  response.statusCode = 400 // email中没有@字符,返回状态码400
  response.setHeader("Content-Type", "application/json; charset=utf8") // 设置响应头
  response.write(`{ // 服务端返回JSON格式字符串
    "errors": {
      "email": "invalid"
    }
  }`)
}

  在服务器判断请求体的数据(如email)没有格式错误的问题后就需要判断此email是否有被注册过。主要方式就是读取数据库文件,查看里面是否有相同的email数据。

let users = fs.readFileSync('./db/users.json', 'utf8') // 读取数据库文件,这里数据库格式我是以JSON格式储存
// 这里try、catch的用法主要是防止数据库中的格式出错导致程序无法运行。
//如果try中的语法出错(即数据库格式错误),就执行catch中的语句,清空数据库。
try {
  users = JSON.parse(users) // 将JSON字符串转换为对象
} catch (error) {
  users = [] 
}
let inUsers = false
for (let i = 0; i < users.length; i++) { // 遍历整个数据库对象
  if (users[i].email === email) { // 判断数据库中是否存在请求体的数据
  inUsers = true
  break 
  // 如果存在将变量inUsers的值改为true并跳出循环
}

  最后这一部分就是将正确的数据写入数据库内,现在注册部分的前端与后端代码都结束了,接下来我要说登录部分了。

if (inUsers) { 
  response.statusCode = 400
  response.setHeader("Content-Type", "application/json; charset=utf8")
  response.write(`{
    "errors": {
      "email": "used"
    }
  }`)
} else { //email没有被注册过
  users.push({ email: email, password: password }) // 将数据写入数组中
  let usersString = JSON.stringify(users) // 将其转为JSON格式
  fs.writeFileSync('./db/users.json', usersString) // 将数据写入数据库内
  response.statusCode = 200 // 返回状态码200
}

登录
  • 登录页面最重要的三部分是登录邮箱、密码与登入按钮 。用户分别输入邮箱、密码后点击登录按钮进行登录操作。
  • 前端部分要做的事主要是判断用户是否在以上两个部分输入了信息,接着判断邮箱的格式是否正确(前端也可不进行判断邮箱的格式,因为后端服务器也会判断一次)。
  • 当用户内容输入正确后,客户端会将用户所输入的内容传给服务器。服务器得到信息后会再一次判断信息的格式等是否符合要求,无误后将得到的信息与数据库中的信息作比较。
  • 如果在数据库中能找到邮箱和密码与传入信息相同,则服务器设置cookie并返回HTTP状态码200给客户端,前端得到登录成功的信息就跳转到登录成功的页面;如果不同则返回HTTP状态码401给客户端,让客户端提示用户邮箱与密码不匹配、登录失败。
登录部分前端代码

登录的前端部分代码与注册的大体相同,逻辑也差不多,这里我就不写出来了。


登录页面样式
登录部分后端代码

登录部分有些代码与注册部分一样,像取得请求体中的信息那部分我就没有写出。

let users = fs.readFileSync('./db/users.json', 'utf8') // 读取数据库信息
let usersList = JSON.parse(users) // 将JSON格式的数据库信息转为对象
let found
for (let i = 0; i < usersList.length; i++) { 
  let user = usersList[i]
  if (user.email === email && user.password === password) { // 判断用户输入信息是否与数据库中的信息匹配
    found = true
    break
  }
}
if (found) {
  response.setHeader('set-Cookie', `sign_in_email=${email}`) // 匹配成功,设置cookie返回给客户端
  response.statusCode = 200 // 返回HTTP状态码200
} else {
  response.statusCode = 401 // 匹配失败,返回状态码401,提示用户登录失败
}

Cookie

  前面我有提到cookie这个东西,Cookie主要是指某些网站为了辨别用户的身份而存储在用户本地终端上的数据。那接下来我就简单介绍一下cookie是什么、有什么特点。

1.Cookie是什么?
  • cookie是客户端访问服务器后,服务器传给客户端的一段数据。
  • 客户端需要保存这段数据,不得轻易删除。
  • 以后每次客户端访问该服务器都必须带上这段数据。
1.Cookie有什么特点?
  • 服务端通过Set-Cookie响应头设置Cookie。
  • 客户端得到Cookie之后,每次访问相同域名的网页时都要带上这个Cookie。
  • 服务器读取Cookie就知道了用户的登录信息。
  • 客户端要在一段时间内保存这个Cookie,
  • Cookie默认在用户关闭页面后失效,但是后端代码可以任意设置过期时间。
  • Cookie的存储大小为4K。

  以上我简单介绍了一下Cookie,想要了解更多的Cookie知识可以去MDN查询了解。Cookie有一个很大的缺点那就是稍微有点前端知识就可以随意串改Cookie,这样会导致有人恶意入侵获取所有用户隐私信息,为了防止这种情况出现配合session来加强Cookie的安全性,具体如何实现各位可以百度一下(or google)。


  至此网页注册与登录两个部分的过程代码解析就结束了,看到这里你对网页注册和登录功能是如何实现的会有一个大概的了解,但是这么多代码可能看起来就会害怕(哈哈哈,我也是),如果愿意你可以有空自己写一个demo实现一下,这样会加深理解!

PS:我现在还是一个前端初学者,如果文中有什么地方写的不准确麻烦提出,我会尽快修改的!
PSS:如果你想看全部代码请点击它--->注册和登录代码
PSSS:之前说的要写JSONP与AJAX的博客要延后了,最近写了个小玩意就是眼球会跟着鼠标转动,过两天写篇博客演示一下如何用JS实现这个功能~(不知道要拖到啥时候写)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容