Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodejs教程09:实现一个带接口请求的简单服务器 #40

Open
chencl1986 opened this issue Mar 18, 2019 · 0 comments
Open

Nodejs教程09:实现一个带接口请求的简单服务器 #40

chencl1986 opened this issue Mar 18, 2019 · 0 comments

Comments

@chencl1986
Copy link
Owner

阅读更多系列文章请访问我的GitHub博客,示例代码请访问这里

带接口请求的简单服务器需求

虽然当前还未涉及到数据库的知识,但已经可以通过文件读写,实现一个简单的服务器,需求如下:

  1. 用户通过GET方法请求/reg接口,实现注册流程。
  2. 用户通过POST方法请求/login接口,实现登录流程。
  3. 非接口请求则直接返回相应文件。

实现思路

  1. 新建users.json文件,用于存放用户列表数据。
  2. 新建index.html文件,实现表单及注册、登录的前端请求功能。
  3. 服务端判断请求路径,决定是前端是通过接口校验用户数据,还是请求HTML文件。
  4. 若是接口请求,则通过用户列表判断用户状态,实现注册和登录流程。

代码及示例

进入/lesson09文件夹,运行node server.js命令,在浏览器访问http://localhost:8080/index.html即可查看效果。

index.html代码如下:

示例代码:/lesson09/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  用户:<input type="text" name="username" id="username"><br/>
  密码:<input type="text" name="password" id="password"><br/>
  <input type="button" value="注册" id="reg">
  <input type="button" value="登录" id="login">
  <script>
    // 注册
    document.querySelector('#reg').addEventListener('click', async function () {
      const response = await fetch(`/reg?username=${document.querySelector('#username').value}&password=${document.querySelector('#password').value}`)
      const result = await response.json()
      console.log(result)
      alert(result.msg)
    })

    // 登录
    document.querySelector('#login').addEventListener('click', async function () {
      const response = await fetch(`/login`, {
        method: 'POST',
        body: JSON.stringify({
          username: document.querySelector('#username').value,
          password: document.querySelector('#password').value
        })
      })
      const result = await response.json()
      console.log(result)
      alert(result.msg)
    })
  </script>
</body>
</html>

server.js代码如下:

示例代码:/lesson09/server.js

const http = require('http')
const url = require('url')
const fs = require('fs')
const querystring = require('querystring')

const server = http.createServer((req, res) => {
  // 定义公共变量,存储请求方法、路径、数据
  const method = req.method
  let path = ''
  let get = {}
  let post = {}

  // 判断请求方法为GET还是POST,区分处理数据
  if (method === 'GET') {
    // 使用url.parse解析get数据
    const { pathname, query } = url.parse(req.url, true)

    path = pathname
    get = query

    complete()
  } else if (method === 'POST') {
    path = req.url
    let arr = []

    req.on('data', (buffer) => {
      // 获取POST请求的Buffer数据
      arr.push(buffer)
    })

    req.on('end', () => {
      // 将Buffer数据合并
      let buffer = Buffer.concat(arr)

      // 处理接收到的POST数据
      post = JSON.parse(buffer.toString())

      complete()
    })
  }

  // 在回调函数中统一处理解析后的数据
  function complete() {
    try {
      if (path === '/reg') {
        // 获取get请求数据
        const {
          username,
          password
        } = get

        // 读取user.json文件
        fs.readFile('./users.json', (error, data) => {
          if (error) {
            res.writeHead(404)
          } else {
            // 读取用户数据
            const users = JSON.parse(data.toString())
            const usernameIndex = users.findIndex((item) => {
              return username === item.username
            })

            // 判断用户名是否存在
            if (usernameIndex >= 0) {
              res.write(JSON.stringify({
                error: 1,
                msg: '此用户名已存在'
              }))
              res.end()
            } else {
              // 用户名不存在则在用户列表中增加一个用户
              users.push({
                username,
                password
              })

              // 将新的用户列表保存到user.json文件中
              fs.writeFile('./users.json', JSON.stringify(users), (error) => {
                if (error) {
                  res.writeHead(404)
                } else {
                  res.write(JSON.stringify({
                    error: 0,
                    msg: '注册成功'
                  }))
                }
                res.end()
              })
            }
          }
        })
      } else if (path === '/login') {
        const {
          username,
          password
        } = post

        // 读取users.json
        fs.readFile('./users.json', (error, data) => {
          if (error) {
            res.writeHead(404)
          } else {
            // 获取user列表数据
            const users = JSON.parse(data.toString())
            const usernameIndex = users.findIndex((item) => {
              return username === item.username
            })

            if (usernameIndex >= 0) {
              // 用户名存在,则校验密码是否正确
              if (users[usernameIndex].password === password) {
                res.write(JSON.stringify({
                  error: 0,
                  msg: '登录成功'
                }))
              } else {
                res.write(JSON.stringify({
                  error: 1,
                  msg: '密码错误'
                }))
              }
            } else {
              res.write(JSON.stringify({
                error: 1,
                msg: '该用户不存在'
              }))
            }
          }
          res.end()
        })
      } else {
        // 若不是注册或登录接口,则直接返回相应文件
        fs.readFile(`.${path}`, (error, data) => {
          if (error) {
            res.writeHead(404)
          } else {
            res.write(data)
          }
          res.end()
        })
      }
    } catch (error) {
      console.error(error);
    }
  }
})

server.listen(8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant