流程:
前端:
1.注册
2.登录
3.首页
后端:
1.注册
url:/register
type:post
params:{
user:'******'(require),
pwd:'******'(require)
}
res:{
code:200,
status:1,(0 注册失败,1 注册成功),
err:'失败原因',
info:{
userID:1,(后台生成)
user:'******',
pwd:'******'
},
msg:"注册成功"
}
2.登录
req:
url:/login
type:post
params:{
user:'******'(require),
pwd:'******'(require)
}
接下来,按照上述流程写后端:
1.创建user.json
2.创建app.js
const http = require('http');
const { URL } = require('url');
const fs = require('fs');
const path = require('path');
// 引⼊模块
const mime = require('./mime.json')
// req:请求,后端给前端
// res:响应,前端给后端
http.createServer((req, res) => {
// 将req.url 进⾏处理
let myUrl = new URL('http://localhost:3000' + req.url);
let url = myUrl.pathname; //路由
static(req, res, myUrl); //是否读取静态⽂件
if (url === '/register') {
//注册
doPost(req, (obj) => {
doRegister(res, obj);
});
} else if (url === '/login') {
//登录
doPost(req, (obj) => {
doLogin(res, obj);
});
}
}).listen(3000, () => {
console.log('http server is running on port 3000')
})
// 读取静态⽂件
function static(req, res, myUrl) {
if (myUrl.pathname.includes('.')) {
// 说明这是个静态⽂件
// 1. 确定静态⽂件的路径
let filepath = __dirname + myUrl.pathname;
// ⽂件后缀名
let ext = path.extname(filepath);
let type = mime[ext];
// 2. 读取他
fs.readFile(filepath, (err, data) => {
// 3. 返回他
// ⼀定要写响应头
res.writeHead(200, { 'content-type': type })
res.end(data);
})
}
}
// 完成post数据接收
function doPost(req, cb) {
let data = ''; //数据
// 分段接收数据
req.on('data', chunk => {
// chunk是个buffer(二进制数据流)
data += chunk;
})
// 数据接受完毕
req.on('end', () => {
let obj = search2obj(data.toString());
cb(obj); //调⽤回调函数
})
}
function search2obj(string) {
// string = 'key=value&key=value'
let obj = {};
// 先分离 &
let arr = string.split('&');
arr.forEach(str => {
// str = 'key=value'
// 再分离 =
let arr2 = str.split('=');
// arr2 = ['key', 'value']
let key = arr2[0];
let value = arr2[1];
obj[key] = value;
})
return obj;
}
function doLogin(res, obj) {
// let obj = {
// user: myUrl.searchParams.get('user'),
// pwd: myUrl.searchParams.get('pwd')
// }
if (!myRule(obj.user) || !myRule(obj.pwd)) {
// 不合规
res.end(JSON.stringify({
code: 200,
status: 0,
err: '⽤户名或者密码请按规定填写!'
}))
return;
}
let users = getAllUsers();
if (!users) {
// 读取内容失败
res.end(JSON.stringify({
code: 200,
status: 0,
err: '系统繁忙,请稍后再试!'
}))
return;
}
users = JSON.parse(users);
let uu = null; //⽬标⽤户
// 判断⽤户名是否⼀样
users.some(item => {
if (item.user === obj.user) {
uu = item;
return true;
}
return false;
})
if (!uu || uu.pwd !== obj.pwd) {
// ⽤户不存在或密码错误
res.end(JSON.stringify({
code: 200,
status: 0,
err: 'user or pwd is wrong!'
}))
return;
}
res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' })
res.end(`
<script>
alert('登录成功');
location.href = 'http://localhost:3000/ll/index.html';
</script>
`)
}
function doRegister(res, obj) {
// console.log(req);
//处理 searchParams to obj
// get 提交数据在req.url⾥
// post 提交 需要使⽤事件来接受
// let obj = {
// user: myUrl.searchParams.get('user'),
// pwd: myUrl.searchParams.get('pwd')
// }
console.log(obj);
// 判断 ⽤户名 密码是否合规
if (!myRule(obj.user) || !myRule(obj.pwd)) {
// 不合规
res.end(JSON.stringify({
code: 200,
status: 0,
err: '⽤户名或者密码请按规定填写!'
}))
return;
}
// 2. 获取 user.json 所有的数据
let users = getAllUsers();
if (!users) {
// 读取内容失败
res.end(JSON.stringify({
code: 200,
status: 0,
err: '系统繁忙,请稍后再试!'
}))
return;
}
// 3. 判断 obj.user是否存在
users = JSON.parse(users);
if (users.some(item => item.user === obj.user)) {
// 存在
res.end(JSON.stringify({
code: 200,
status: 0,
err: '⽤户名已存在!'
}))
return;
}
// 为obj添加⼀个id
obj.id = users.length + 1;
users.push(obj);
// 将users重新写⼊ user.json
reSetUsers(users);
res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' })
res.end(`
<script>
alert('注册成功');
location.href = 'http://localhost:3000/ll/login.html';
</script>
`)
}
// 正则 验证
// 规则:不允许出现特殊符号, 6-20位
function myRule(string) {
const rule = /^\w{6,20}$/;
return rule.test(string);
}
// 获取 user.json 的数据
function getAllUsers() {
let path = __dirname + '/db/user.json';
return fs.readFileSync(path, 'utf8');
}
// 重新写⼊ user.json
function reSetUsers(users) {
let path = __dirname + '/db/user.json';
return fs.writeFileSync(path, JSON.stringify(users));
}
3.编写前端页面
创建index.html,login.html,register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>欢迎来到聊聊</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
<link rel="stylesheet" href="css/public.css">
</head>
<body>
<h1>登录</h1>
<form action="/login" method="post">
<div class="user">
<input type="text" name="user" placeholder="请输入用户名" required>
</div>
<div class="pwd">
<input type="password" name="pwd" placeholder="请输入密码" required>
</div>
<input type="submit">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册</title>
<link rel="stylesheet" href="css/public.css">
</head>
<body>
<h1>注册</h1>
<form action="/register" method="post">
<div class="user">
<input type="text" name="user" placeholder="请输入用户名" required>
</div>
<div class="pwd">
<input type="password" name="pwd" placeholder="请输入密码" required>
</div>
<input type="submit">
</form>
</body>
</html>
终端开启:
服务器:
点击确定跳转到登录页面
点击确定跳转到首页
看user.json中此时已经有了刚才的数据