动态服务器
2022-08-03 本文已影响0人
饥人谷_折纸大师
静态服务器和动态服务器如何区分
判断依据
- 是否请求了数据库
如果没有请求数据库那么就是,静态服务器。
如果请求了数据库那么就是,动态服务器。
读写数据库模版
const fs = require("fs"); //用来读取文件
//读数据库
const usersString = fs.readFileSync("./db/users.json").toString(); //读取当前目录下的db目录下的users.json文件,并“以文本方式表示该字符串
const usersArray = JSON.parse(usersString); //把字符串变为对应的数组对象(反序列化)
//写数据库
const user3 = { id: "3", name: "Tom", password: "yyy" };
usersArray.push(user3); //把数据放入这个数组,这个数组是本地的,还没有放入数据库中
const string = JSON.stringify(usersArray); //转化为字符串(序列化)
fs.writeFileSync("./db/users.json", string); //写入数据库中
利用动态服务器的做一些实现(用户注册)
目标1:实现用户注册功能
过程:用户输入用户名和密码,users.json里面多一行数据
思路:
- 前端写一个form表单,让用户填写name和password
- 前端监听submit事件,
- 前端发送POST请求,数据位于请求体
- 后端接收POST请求,
- 后端获取请求体的name和password
- 后端存储数据
代码实现:
写表单:
<form id="registerForm">
<div>
<label for="">用户名 <input type="text" name="name"></label>
</div>
<div>
<label for="">密码 <input type="password" name="password"></label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
监听submit,并发送POST请求
const $form = $('#registerForm')
$form.on('submit', (e) => {
e.preventDefault()//标点有默认事件,我们需要把它阻止掉
const name = $form.find('input[name=name]').val()//在form里面找name=name的input,并获取它的值
const password = $form.find('input[name=password]').val()//在form里面找到name=password的input,并获取它的值
console.log(name, password)
$.ajax({
//利用ajax把数据上传给服务器
method: 'POST',
contentType: 'text/json;charset=UTF-8',
url: '/register',
data: JSON.stringify({ name, password })
}).then(() => {
alert('注册成功')
location.href = '/sign_in.html'
}, () => { })
})
后端部分:
if (path === "/register" && method === "POST") {
response.setHeader("Content-Type", "text/html;charset=UTF-8");
const userArray = JSON.parse(fs.readFileSync("./db/users.json")); //读数据库并反序列化
const array = []; //因为数据有可能是分段上传的,所以我要声明一个空数组,把数据放入这个数组中
request.on("data", (chunk) => {
//监听response的数据提交事件,chunk是一小段数据,即只要有数据提交,那么就把这一段数据存入数组中
array.push(chunk);
});
request.on("end", () => {
const string = Buffer.concat(array).toString(); //这个API可以把不同的数据合成一个字符串
// console.log(string); //此时这个数组应该有全部的数据
const obj = JSON.parse(string); //反序列化
const lastUser = userArray[userArray.length - 1];
const newUser = {
//id为最后一个数据的id+1
id: lastUser ? lastUser.id + 1 : 1, //如果lastUser存在则id为最后一个数据+1,否则id为1
name: obj.name,
password: obj.password,
}; //新数据
userArray.push(newUser); //存入数据库中
fs.writeFileSync("./db/users.json", JSON.stringify(userArray));
});
这就实现了用户注册的功能。
cookie
这时间我们需要做一个登录功能。
目标2:实现用户登录功能
home.html 已经登陆的用户可以看到自己的用户名
登陆页sign_in.html供提交用户名和密码
输入的用户名和密码如果是匹配的,就自动跳转首页
实现思路:
- 前端写一个form表单,让用户填写name和password
- 前端监听submit事件,
- 前端发送POST请求,数据位于请求体
- 后端接收POST请求,
- 后端获取请求体的name和password
6.后端读取数据,看有没有匹配的name和password
如果匹配,后端应该标记用户登录,如何标记?
答案是cookie
cookie是什么
cookie是服务器下发给浏览器的一段字符串
浏览器必须保存这个cookie(除非用户删除)
之后发起相同二级域名的请求(任何请求)时,浏览器必须附上cookie
标记用户
response.setHeader("Set-Cookie", "login=1"); //设置cookie
目标3:显示用户名
const cookie = request.headers["cookie"];
let userId;
try {
userId = cookie
.split(";")
.filter((s) => s.indexOf("session_id=") >= 0)[0]
.split("=")[1];
} catch (error) {}
if (userId) {
const userArray = JSON.parse(fs.readFileSync("./db/users.json"));
const 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();
可以实现home.html渲染前得到用户id并显示
但这样有一个bug就是 用户也可以在开发者工具篡改userid
目标4:防止篡改userid
思路一:加密
将useid加密发送给前端,后端读取时解密。
方法虽然可行,但是有安全漏洞。
漏洞:加密后的内容可以无限期使用。
思路二:把信息隐藏在服务器
把用户信息放在服务器的x里面,再给信息一个随机id
把随机id发送给浏览器,
后端读到id时,通过x[id]获取用户信息
这个x叫做session(会话)