node做渲染服务器的实现
node 可以进行什么样的开发??
1.数据服务器 专门书写接口 前后端分离式的开发
2.渲染服务器 除了书写接口,还要负责页面的返回和渲染, 在 node 中把页面中需要的所有数据直接组装好,返回给前端一个组装好的页面
3.中间层渲染 作为一个中转服务器,提供页面,逻辑: 前端 <-> node 中间层 <-> 数据服务器
渲染服务器的分析:
1.通过url的改变来获取服务器返回的页面,同时发送请求的数据,通过数据,进行数据库对比,进而返回页面
2.文件夹分类:
- public 放静态资源: 前端页面需要的静态资源(js, css, image, audio, ...)
- views 放前端的显示的页面
- db 放数据库操作
- app.js 服务器启动文件
- model 服务器需要用的各种独立封装模块
- ....
以一个简单的登录注册来表示
app.js 服务器启动文件
const http = require('http')
const fs = require('fs')
const urlModel = require('url')
const { selectUser } = require('./db/db_model')
// 准备一个标识符, 表示是否登陆过
let userNikename = '';
http.createServer((req, res) => {
const { url } = req // => const url = req.url
if (url.startsWith('/views')) {
fs.readFile('.' + url, 'utf8', (err, data) => {
if (err) return console.log(err)
if (url === '/views/index.html') {
// 通过userNikename值的变化来改变登录数据的动态变化
data = data.replace('{{ abc }}', userNikename ? userNikename : '请登录')
}
res.end(data)
})
}
if (url.startsWith('/public')) {
fs.readFile('.' + url, (err, data) => {
if (err) return console.log(err)
res.end(data)
})
}
// 判断你是在做登录请求
if (url === '/login') {
let str = ''
// 接收参数
req.on('data', (chunk) => {
str += chunk
})
req.on('end', async () => {
const { username, password } = urlModel.parse('?' + str, true).query
// 查询数据库
const result = await selectUser([username, password])
// 根据查询结果, 想前端返回一些数据
if (result.length) {
userNikename = result[0].username //这里实现userNikename值的动态变化
res.end('{ "message": "登录成功", "code": 1 }')
} else {
res.end('{ "message": "登录失败", "code": 0 }')
}
})
}
}).listen(8080, () => console.log('running at port 8080 ! ^_^'))
view下的两个html文件
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>首页</h1>
<p>你好 {{abc}}</p>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="/public/js/login.js" async defer></script>
</head>
<body>
<form action="">
用户名: <input type="text" name="username" autocomplete="off"><br>
密码: <input type="text" name="password" autocomplete="off"><br>
<button>提交</button>
</form>
</body>
</html>
public下的js和css文件
login.css
* {
margin: 0;
padding: 0;
}
form {
width: 500px;
padding: 30px;
margin: 100px auto;
border: 10px solid pink;
}
form > input {
margin: 20px 0;
}
login.js
const form = document.querySelector('form')
const nameInp = document.querySelector('input[name=username]')
const pwdInp = document.querySelector('input[name=password]')
form.addEventListener('submit', e => {
e.preventDefault()
const username = nameInp.value
const password = pwdInp.value
// 表单验证
const xhr = new XMLHttpRequest()
xhr.open('POST', '/login')
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(`username=${ username }&password=${ password }`)
xhr.onload = function () {
const { code } = JSON.parse(xhr.responseText)
if (code === 1) {
window.location.href = './index.html' //通过返回的code值来判断是否跳转页面,和node的userNikename相对应
}
}
})