如何利用Node.js与JSON搭建简单的动态服务器


Posted in Javascript onJune 16, 2020

一、创建html页面

创建4个页面,index.html、register.html、sign_in.html、home.html

  • index.html 默认主页
  • register.html 用于注册账号
  • sign_in.html 用于登录账号
  • home.html 用于显示登录后的页面

主要代码片段

register.html

<form id="registerForm">
 <div>
  <label for="">用户名:<input type="text" name="name" id=""></label>
 </div>
 <div>
  <label for="">密码:<input type="password" name="password" id=""></label>
 </div>
 <div>
  <button type="submit">注册</button>
 </div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
let $form = $('#registerForm')
$form.on('submit', (e) => {
 e.preventDefault()
 const name = $form.find("input[name=name]").val()
 const password = $form.find('input[name=password').val()
 console.log(name, password)
 // pass AJAX post data
 $.ajax({
  method: 'post',
  url: '/register',
  contentType: 'text/json; charset=UTF-8',
  data: JSON.stringify({
   name, // name: name 
   password // password: password
  })
 }).then(() => {
  alert('注册成功')
  location.href = '/sign_in.html'
 }, () => {})
})
</script>

sign_in.html

<form id="signInForm">
 <div>
  <label for="">用户名:<input type="text" name="name" id=""></label>
 </div>
 <div>
  <label for="">密码:<input type="password" name="password" id=""></label>
 </div>
 <div>
  <button type="submit">登录</button>
 </div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
 let $form = $('#signInForm')
 $form.on('submit', (e) => {
  e.preventDefault()
  // get name password
  const name = $form.find("input[name=name]").val()
  const password = $form.find('input[name=password').val()
  // pass AJAX post data
  $.ajax({
   method: 'POST',
   url: '/sign_in',
   contentType: 'text/json; charset=UTF-8',
   data: JSON.stringify({
    name,
    password
   })
  }).then(() => {
   alert('登录成功')
   location.href = '/home.html'
  }, () => {})
 })
</script>

home.html

<p>
 {{loginStatus}}
</p>
<p>
 你好,{{user.name}}
</p>
<p>
 <a href="sign_in.html">登录</a>
</p>

二、Node服务器

var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]

if (!port) {
 console.log('请输入指定端口。如:\nnode server.js 8888')
 process.exit(1)
}

var server = http.createServer(function (request, response) {
 var parsedUrl = url.parse(request.url, true)
 var pathWithQuery = request.url
 var queryString = ''
 if (pathWithQuery.indexOf('?') >= 0) {
  queryString = pathWithQuery.substring(pathWithQuery.indexOf('?'))
 }
 var path = parsedUrl.pathname
 var query = parsedUrl.query
 var method = request.method

 /******** main start ************/
 // 读取 session 文件,转化为对象
 const session = JSON.parse(fs.readFileSync('./session.json').toString())

 if (path === '/sign_in' && method === 'POST') {
  // 读数据库
  let userArray = JSON.parse(fs.readFileSync('./database/users.json'))
  const array = []
  // 每次接受数据就添加进数组
  request.on('data', (chunk) => {
   array.push(chunk)
  })
  request.on('end', () => {
   // 转化字符串
   const string = Buffer.concat(array).toString()
   // 在转化为对象
   const obj = JSON.parse(string)
   // 找到符合的 user
   const user = userArray.find(user => user.name === obj.name && user.password === obj.password) // 成功返回符合的对象,失败返回undefined
   if (user === undefined) { // 失败
    response.statusCode = 400
    response.setHeader('content-Type', 'text/JSON; charset=UTF-8')
    response.end(`{"errorCode":4001}`)
   } else { // 成功
    response.statusCode = 200
    // 设置 Cookie
    const random = Math.random()
    session[random] = {
     user_id: user.id
    }
    // 写入数据
    fs.writeFileSync('./session.json', JSON.stringify(session))
    response.setHeader("Set-Cookie", `'session_id=${random}; HttpOnly'`)
    response.end()
   }
  })
 } else if (path === '/home.html') {
  // 获取 Cookie
  const cookie = request.headers['cookie']
  let sessionId
  try { // 读取 Cookie 中的 id 值
   sessionId = cookie.split(';').filter(s => s.indexOf('session_id=') >= 0)[0].split('=')[1]
  } catch (error) {}
  if (sessionId && session[sessionId]) {
   // 从 session 中读取对应的值
   const userId = session[sessionId].user_id
   // 读数据库
   let userArray = JSON.parse(fs.readFileSync('./database/users.json'))
   // 找到符合的 user
   let user = userArray.find(user => user.id === userId)
   const homeHtml = fs.readFileSync('./public/home.html').toString()
   let string
   if (user) {
    string = homeHtml.replace('{{loginStatus}}', '已登录').replace('{{user.name}}', user.name)
    response.write(string)
   }
  } else {
   // 读取源文件内容
   const homeHtml = fs.readFileSync('./public/home.html').toString()
   // 替换文字
   const string = homeHtml.replace('{{loginStatus}}', '未登录').replace('{{user.name}}', '')
   response.write(string)
  }
  response.end()
 } else if (path === '/register' && method === 'POST') {
  response.setHeader('Content-Type', 'text/html; charset=UTF-8')
  // read database
  let userArray = JSON.parse(fs.readFileSync('./database/users.json')) // read database
  const array = []
  request.on('data', (chunk) => {
   array.push(chunk)
  })
  request.on('end', () => {
   // convert string
   const string = Buffer.concat(array).toString()
   // convert obj
   const obj = JSON.parse(string)
   // last user id
   const lastUser = userArray[userArray.length - 1]
   // new user
   const newUser = {
    id: lastUser ? lastUser.id + 1 : 1,
    name: obj.name,
    password: obj.password
   }
   userArray.push(newUser)
   // write data
   fs.writeFileSync('./database/users.json', JSON.stringify(userArray))
  })
  response.end()
 } else {
  response.statusCode = 200
  let content
  // setting index
  const filePath = path === '/' ? '/index.html' : path
  // judge type
  const index = filePath.lastIndexOf('.')
  const suffix = filePath.substring(index)
  const fileType = {
   '.html': 'text/html',
   '.css': 'text/css',
   '.js': 'text/javascript'
  }
  response.setHeader('Content-Type', `${fileType[suffix] || "text/html"};charset=utf-8`)
  try {
   content = fs.readFileSync(`./public${filePath}`)
  } catch (error) {
   content = '文件路径不存在'
   response.statusCode = 404
  }
  response.write(content)
  response.end()
 }

 /******** main end ************/
})

server.listen(port)
console.log('监听 ' + port + ' 成功!请输入下列地址访问\nhttp://localhost:' + port)

三、主要思路

register.html

使用jQuery的ajax将数据发送请求 /register 给后端,成功则跳转到 sign_in.html

数据需要使用 JSON.stringify 转化为字符串在提交

/register

读取 users.json 的数据,创建一个空数组,将传递过来的参数 push 进去。将数组转换为字符串,在转换为对象。
获取数据库中最小的 id 值,将数据组成新的对象,添加进入 数据库 中。

sign_in.html

使用ajax将数据发送请求 /sign_in 给后端,成功则跳转 home.html

/sign_in

读取 users.json 的数据,创建一个空数组,将传递过来的参数 push 进去。将数组转换为字符串,在转换为对象。
在读取后的数据库中,查找有没有符合条件的 user,成功返回读取后的对象,失败返回 undefined。
如果成功,设置随机数,将 随机数的值 与 user的id 绑定。并添加到 session.json 中。然后 setHeader,将cookie发送到浏览器。

/home

获取登入成功后 cookie 的值。读取 session 中对应的随机数。如果随机数和session对应的随机数值存在,就显示已登录,否则显示未登录

总结

到此这篇关于如何利用Node.js与JSON搭建简单的动态服务器的文章就介绍到这了,更多相关Node.js与JSON搭建动态服务器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
无缝滚动js代码通俗易懂(自写)
Jun 19 Javascript
js监听键盘事件示例代码
Jul 26 Javascript
jQuery控制TR显示隐藏的三种常用方法
Aug 21 Javascript
深入理解JS函数的参数(arguments)的使用
May 28 Javascript
jQuery深拷贝Json对象简单示例
Jul 06 Javascript
vue分页组件table-pagebar使用实例解析
Nov 15 Javascript
JS 实现随机验证码功能
Feb 15 Javascript
对angularjs框架下controller间的传值方法详解
Oct 08 Javascript
vue-路由精讲 二级路由和三级路由的作用
Aug 06 Javascript
微信小程序实现简单的select下拉框
Nov 23 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
JavaScript实现复选框全选功能
Apr 11 Javascript
js+css实现全屏侧边栏
Jun 16 #Javascript
JavaScript装箱及拆箱boxing及unBoxing用法解析
Jun 15 #Javascript
通过实例解析JavaScript for in及for of区别
Jun 15 #Javascript
vue proxy 的优势与使用场景实现
Jun 15 #Javascript
原生JS利用transform实现banner的无限滚动示例代码
Jun 15 #Javascript
koa中间件核心(koa-compose)源码解读分析
Jun 15 #Javascript
为react组件库添加typescript类型提示的方法
Jun 15 #Javascript
You might like
php实现网站插件机制的方法
2009/11/10 PHP
解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
2013/06/26 PHP
Javascript实现的分页函数
2006/12/22 Javascript
javascript multibox 全选
2009/03/22 Javascript
jQuery实现原理的模拟代码 -6 代码下载
2010/08/16 Javascript
40款非常棒的jQuery 插件和制作教程(系列一)
2011/10/26 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
2012/09/14 Javascript
让ie6也支持websocket采用flash封装实现
2013/02/18 Javascript
JavaScript中的prototype.bind()方法介绍
2014/04/04 Javascript
wap手机图片滑动切换特效无css3元素js脚本编写
2014/07/28 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
2016/06/01 Javascript
jQuery右下角悬浮广告实例
2016/10/17 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
2016/12/18 Javascript
Bootstrap进度条学习使用
2017/02/09 Javascript
JavaScript表单验证的两种实现方法
2017/02/11 Javascript
深入理解Node module模块
2018/03/26 Javascript
ionic grid(栅格)九宫格制作详解
2018/06/30 Javascript
在element-ui的select下拉框加上滚动加载
2019/04/18 Javascript
微信小程序云开发之云函数详解
2019/05/16 Javascript
JavaScript实现网页计算器功能
2020/10/29 Javascript
python深度优先搜索和广度优先搜索
2018/02/07 Python
python实现手机通讯录搜索功能
2018/02/22 Python
Python利用matplotlib.pyplot绘图时如何设置坐标轴刻度
2018/04/09 Python
Python reduce函数作用及实例解析
2020/05/08 Python
基于Python的Jenkins的二次开发操作
2020/05/12 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
涂鸦板简单实现 Html5编写属于自己的画画板
2016/07/05 HTML / CSS
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
西班牙第一的网上药房:PromoFarma.com
2017/04/17 全球购物
绿色美容,有机护肤品和化妆品:Safe & Chic
2018/10/29 全球购物
户外宣传策划方案
2014/05/25 职场文书
课外访万家心得体会
2014/09/03 职场文书
企业法人授权委托书范本
2014/09/23 职场文书
2015年乡镇流动人口工作总结
2015/05/12 职场文书
《清澈的湖水》教学反思
2016/02/17 职场文书