1.什么叫动态服务器
动态服务器就是访问数据库,静态服务器不访问数据库.
2.实现用户注册
2.1目标
用户注册一个账号,数据库增加一条数据
2.2思路
1.前端创建一个form表单,用户提交账号密码
2.前端监听submit事件
3.前端发送post请求,数据位于请求体
4.后端接收post请求
5.后端获取到账号和密码
6.后端储存数据
2.3代码实现
前端代码
//创建form表单
<form id="registerForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
//提交按钮
<button type="submit">注册</button>
</div>
</form>
//引用jquery
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
<script>
//监控submit事件
const $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)
//发送AJAX请求
$.ajax({
method:'POST',
url:'/register',
contentType:'text/json;charset=UTF-8',
data:JSON.stringify({name,password}),
}).then(()=>{
//弹出提示框
alert('注册成功')
location.href='/sign_in.html'
},()=>{})
})
</script>
后端代码(node写的)
else 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) => {
array.push(chunk)
})
request.on('end', () => {
//不同的数据合成字符串
const string = Buffer.concat(array).toString()
//变成对象
const obj = JSON.parse(string);
//ID为最后一个人的用户
const lastUser = userArray[userArray.length - 1]
const newUser = {
//id 为最后一个人用户的id+1
id: lastUser ? lastUser.id + 1 : 1,
name: obj.name,
password: obj.password
};
userArray.push(newUser)
//新的写到数据库里面
fs.writeFileSync('./db/users.json', JSON.stringify(userArray))
response.end('很好')
})

3.实现用户登录
3.1目标
1.首页home.html,当用户登录成功后可以显示用户的账号
2.登录页sign_in.html,用户提交账号和密码
3.如果登录成功跳转首页
3.2实现思路
1.前端创建一个form表单,用户提交账号密码
2.前端监听submit事件
3.前端发送post请求,数据位于请求体
4.后端接收post请求
5.后端获取到账号和密码
6.后端看是不是可以匹配到账号和密码
可是如果能匹配,后端需要标记已经登录,可是怎么标记?碰到问题了,所以目标应该小一点,标记已经登录,需要实现这个目标我们不得不说到cookie
4.1cookie
4.2Cookie定义
Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,浏览器必须保存这个Cookie,之后发起相同二级域名请求时,必须带上这个Cookie.Cookie就像公园的门票,有门票就是已经登录.
4.3创建Cookie
服务器使用 [Set-Cookie
] 响应头部向用户代理(一般是浏览器)发送 Cookie信息。一个简单的 Cookie 可能像这样:
Set-Cookie: <cookie名>=<cookie值>
4.4home.html如何知道谁登录了
可以用数据库里的id
[{"id":1,"name":"1111","password":"2222"},{"id":2,"name":"1111","password":"2222"},{"id":3,"name":"1111","password":"2222"},{"id":4,"name":"111","password":"44444"},{"id":5,"name":"1111","password":"2222"},{"id":6,"name":"2222","password":"5555"}]
可是问题来了,用户可以修改id,怎么解决这个问题?
5.防止篡改ID
5.1思路一:加密
将id加密发送给前端,后端读取id时解密,此方法可行,存在安全漏洞(加密后的内容可以无期限使用)解决办法:JWT
5.2把信息隐藏在服务器
1.把用户信息放在服务器的X里,再给信息一个随机id
2.把随机id发给浏览器
3.后端下次读取到id时,通过x[id]获取用户信息
为什么无法篡改id?
因为id很长,而且随机
这个X又叫session

代码实现:
登录页面
<form id="signInForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">登录</button>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
<script>
//监控submit事件
const $form=$('#signInForm')
$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)
//发送AJAX请求
$.ajax({
method:'POST',
url:'/sign_in',
contentType:'text/json;charset=UTF-8',
data:JSON.stringify({name,password}),
}).then(()=>{
alert('登录成功')
location.href='/home.html'
},()=>{})
}) ;
首页
<p>
{{user.name}}
{{loginStatus}}
</p>
<p>
<a href="sign_in.html"></a>
</p>
后端代码
const session = JSON.parse(fs.readFileSync('./session.json').toString())
console.log("有个傻子发请求过来啦!路径(带查询参数)为:" + pathWithQuery);
if (path === "/sign_in" && method === "POST") {
const userArray = JSON.parse(fs.readFileSync("./db/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); // name password
const user = userArray.find(
user => user.name === obj.name && user.password === obj.password
);
if (user === undefined) {
response.statusCode = 400;
response.setHeader("Content-Type", "text/json; charset=utf-8");
} else {
response.statusCode = 200;
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") {
// 写不出来
const cookie = request.headers["cookie"];
let sessionId;
try {
sessionId = cookie
.split(";")
.filter(s => s.indexOf("session_id=") >= 0)[0]
.split("=")[1];
} catch (error) {}
if (sessionId && session[sessionId]) {
const userId = session[sessionId].user_id
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) {
console.log(user)
string = homeHtml.replace("{{loginStatus}}", "已登录")
.replace('{{user.name}}', user.name)
}
response.write(string);
} else {
const homeHtml = fs.readFileSync("./public/home.html").toString();
const string2 = homeHtml.replace("{{loginStatus}}", "未登录")
.replace('{{user.name}}', '')
response.write(string2);
}
response.end()

以上代码上传在Github, https://zhuzikaihua888.github.io/static-server/有需要可以下载.
本文为本人的原创文章,著作权归本人和饥人谷所有,转载务必注明来源.
网友评论