如何利用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 上下左右键控制焦点(示例代码)
Dec 14 Javascript
JavaScript设计模式之工厂模式和构造器模式
Feb 11 Javascript
基于jquery css3实现点击动画弹出表单源码特效
Aug 31 Javascript
详解AngularJS中的表单验证(推荐)
Nov 17 Javascript
JavaScript中无法通过div.style.left获取值的解决方法
Feb 19 Javascript
jQuery EasyUI 折叠面板accordion的使用实例(分享)
Dec 25 jQuery
vue2.0页面前进刷新回退不刷新的实现方法
Jul 31 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
Apr 26 Javascript
详解auto-vue-file:一个自动创建vue组件的包
Apr 26 Javascript
JS实现简单省市二级联动
Nov 27 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
Apr 21 Javascript
JS异步宏队列与微队列原理区别详解
Jul 02 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
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
javascript 终止函数执行操作
2014/02/14 Javascript
js动态切换图片的方法
2015/01/20 Javascript
javascript使用avalon绑定实现checkbox全选
2015/05/06 Javascript
javascript清空table表格的方法
2015/05/14 Javascript
JS组件Bootstrap Select2使用方法解析
2016/05/30 Javascript
用原生JS对AJAX做简单封装的实例代码
2016/07/13 Javascript
Vue表单实例代码
2016/09/05 Javascript
Angular2学习笔记——详解NgModule模块
2016/12/02 Javascript
Vue.js之slot深度复制详解
2017/03/10 Javascript
ES6生成器用法实例分析
2017/04/10 Javascript
使用jquery的jsonp如何发起跨域请求及其原理详解
2017/08/17 jQuery
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
在Vue中使用echarts的方法
2018/02/05 Javascript
vue2.0在没有dev-server.js下的本地数据配置方法
2018/02/23 Javascript
Vue.js进阶知识点总结
2018/04/01 Javascript
vue 如何从单页应用改造成多页应用
2020/10/23 Javascript
[01:36:19]Secret vs NB 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[02:55]含熏伴清风,风行者至宝、屠夫身心及典藏宝瓶二展示
2020/09/08 DOTA
python进阶教程之动态类型详解
2014/08/30 Python
Python解析Excle文件中的数据方法
2018/10/23 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
2020/03/06 Python
Django使用list对单个或者多个字段求values值实例
2020/03/31 Python
python代码中怎么换行
2020/06/17 Python
python查询MySQL将数据写入Excel
2020/10/29 Python
基于css3实现漂亮便签样式
2013/03/18 HTML / CSS
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
计算机应用专业推荐信
2013/11/13 职场文书
国庆宣传标语
2014/06/30 职场文书
优秀工作者事迹材料
2014/12/26 职场文书
妇产科护理心得体会
2016/01/22 职场文书
python实现网络五子棋
2021/04/11 Python
正确的理解和使用Django信号(Signals)
2021/04/14 Python
如何使用CocosCreator对象池
2021/04/14 Javascript
python基于opencv批量生成验证码的示例
2021/04/28 Python
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers