使用Node.js和JSON搭建簡單的動態服務器

1、建立html頁面

建立4個頁面,index.html、register.html、sign_in.html、home.htmljavascript

  • index.html 默認主頁
  • register.html 用於註冊帳號
  • sign_in.html 用於登陸帳號
  • home.html 用於顯示登陸後的頁面

主要代碼片斷

register.htmlcss

<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.htmlhtml

<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.htmljava

<p>
    {{loginStatus}}
</p>
<p>
    你好,{{user.name}}
</p>
<p>
    <a href="sign_in.html">登陸</a>
</p>
複製代碼

2、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)
複製代碼

3、主要思路

register.html

使用jQuery的ajax將數據發送請求 /register 給後端,成功則跳轉到 sign_in.htmlnode

數據須要使用 JSON.stringify 轉化爲字符串在提交jquery

/register

讀取 users.json 的數據,建立一個空數組,將傳遞過來的參數 push 進去。將數組轉換爲字符串,在轉換爲對象。 獲取數據庫中最小的 id 值,將數據組成新的對象,添加進入 數據庫 中。ajax

sign_in.html

使用ajax將數據發送請求 /sign_in 給後端,成功則跳轉 home.html數據庫

/sign_in

讀取 users.json 的數據,建立一個空數組,將傳遞過來的參數 push 進去。將數組轉換爲字符串,在轉換爲對象。 在讀取後的數據庫中,查找有沒有符合條件的 user,成功返回讀取後的對象,失敗返回 undefined。 若是成功,設置隨機數,將 隨機數的值 與 user的id 綁定。並添加到 session.json 中。而後 setHeader,將cookie發送到瀏覽器。json

/home

獲取登入成功後 cookie 的值。讀取 session 中對應的隨機數。若是隨機數和session對應的隨機數值存在,就顯示已登陸,不然顯示未登陸後端

相關文章
相關標籤/搜索