Nodejs教程09:實現一個帶接口請求的簡單服務器

閱讀更多系列文章請訪問個人GitHub博客,示例代碼請訪問這裏

帶接口請求的簡單服務器需求

雖然當前還未涉及到數據庫的知識,但已經能夠經過文件讀寫,實現一個簡單的服務器,需求以下:html

  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代碼以下:node

示例代碼:/lesson09/index.htmlgit

<!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代碼以下:github

示例代碼:/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)
複製代碼
相關文章
相關標籤/搜索