NodeJS

路由处理

Router

代码示例:

/* login.css */

div {
    background-color: #30363d;
}
// server.js

const http = require('http')

const Router = {}

function use(obj) {
    Object.assign(Router, obj)  // 合并对象
}

function start() {
    http.createServer((req, res) => {
        const myURL = new URL(req.url, 'http://localhost')
        // route(res, myURL.pathname)
        try {
            Router[myURL.pathname](req, res)
        } catch (error) {
            Router['/404'](req, res)
        }
    }).listen(3000, () => {
        console.log('server start')
    })
}

module.exports = {
    start,
    use
}
// api.js

const fs = require("fs");

function render(res, data, type = '') {
    res.writeHead(200, {
        'Content-Type': `${type ? type : 'application/json'};charset=utf8`
    })
    res.write(data)
    res.end()
}

const apiRouter = {
    '/api/loginget': (req, res) => {
        const myURL = new URL(req.url, 'http://localhost')
        if (myURL.searchParams.get('username') === 'username' && myURL.searchParams.get('pwd') === 'password') {
            render(res, `{'ok': 1}`)
        } else {
            render(res, `{'ok': 0}`)
        }
    },
    '/api/loginpost': (req, res) => {
        let post = ''
        req.on('data', chunk => {  // 逐帧收集
            post += chunk
        })
        req.on('end', () => {
            // console.log(post)
            post = JSON.parse(post)
            if (post.usename === 'username' && post.pwd === 'password') {
                render(res, `{'ok': 1}`)
            } else {
                render(res, `{'ok': 0}`)
            }
        })
    }
}

module.exports = {
    apiRouter
}
// index.js

const {start, use} = require('./server')
const {route} = require('./route')
const {apiRouter} = require('./api')

// 注册路由
use(route)
use(apiRouter)

start()
// route.js

const fs = require('fs')
const path = require('path')
const mime = require('mime')

// function route(res, pathname) {
//     switch (pathname) {
//         case '/login':
//             res.writeHead(200, {
//                 'Content-Type': 'text/html;charset=utf8'
//             })
//             res.write(fs.readFileSync('./static/login.html'), 'utf8')
//             break
//         case '/home':
//             res.writeHead(200, {
//                 'Content-Type': 'text/html;charset=utf8'
//             })
//             res.write(fs.readFileSync('./static/home.html'), 'utf8')
//             break
//         default:
//             res.writeHead(404, {
//                 'Content-Type': 'text/html;charset=utf8'
//             })
//             res.write(fs.readFileSync('./static/404.html'), 'utf8')
//     }
// }

function render(res, path, stateCode = 200, type = '', code = 'utf8') {
    res.writeHead(stateCode, {
        'Content-Type': `${type ? type : 'text/html'};charset=utf8`
    })
    res.write(fs.readFileSync(path), code)
    res.end()
}

function readStaticFile(req, res) {
    const myURL = new URL(req.url, 'http://localhost:3000')
    // console.log(path.join(__dirname, '/static', myURL.pathname))
    const pathname = path.join(__dirname, '/static', myURL.pathname)
    // if (myURL.pathname === '/') return false  // 没有配置'/'路由的前提下
    if (fs.existsSync(pathname)) {
        render(res, pathname, 200, mime.getType(myURL.pathname.split('.')[1]))
        return true
    } else {
        return false
    }
}

const route = {
    // '/favicon.ico': (req, res) => {
    //     render(res, './static/favicon.ico', 200, 'image/x-icon', null)
    // },
    '/': (req, res) => {
        render(res, './static/home.html')
    },
    '/login': (req, res) => {
        render(res, './static/login.html')
    },
    '/home': (req, res) => {
        render(res, './static/home.html')
    },
    '/404': (req, res) => {
        if (readStaticFile(req, res)) {  // 是否加载对应的静态资源
            return
        }
        render(res, './static/404.html', 404)
    }
}

module.exports = {
    route
}
// static/js/login.js

const useName = document.querySelector('#useName')
const pwd = document.querySelector('#pwd')
const loginGet = document.querySelector('#loginGet')
const loginPost = document.querySelector('#loginPost')
loginGet.onclick = () => {
    fetch(`/api/loginget?username=${useName.value}&pwd=${pwd.value}`)
        .then(res => res.text())
        .then(res => console.log(res))
        .catch(err => console.log(err))
}
loginPost.onclick = () => {
    fetch(`/api/loginpost`, {
        method: 'POST',
        body: JSON.stringify({
            usename: useName.value,
            pwd: pwd.value
        }),
        headers: {
            'Content-Type': 'application/json'
        }
    })
        .then(res => res.text())
        .then(res => console.log(res))
        .catch(err => console.log(err))
}
<!-- static/login.html -->

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/login.css"/>  <!-- 实际请求的是后端的路由 -->
</head>
<body>
    <div>
        用户名:
        <input type="text" id="useName"/>
    </div>
    <div>
        密码:
        <input type="password" id="pwd"/>
    </div>
    <div>
        <button id="loginGet">登录-GET</button>
        <button id="loginPost">登录-POST</button>
    </div>
    <script src="/js/login.js"></script>
</body>
</html>