- 动态服务器(动态网页)和静态服务器(静态网页)
- 区分依据:是否请求了数据库,请求了就是动态,否则就是静态
- 可以用json文件(users.json)来替代数据库,结构就是一个数组,新建db数据库文件夹
[
{"id":1, "name":"frank","password":"xxx"},
{"id":1, "name":"jack","password":"zzz"}
]
以上代码中的字符串都用双引号"",因为是json文件
node test.js,在vs-code中运行test.js,查看对象类型:
const fs = require('fs');
const usersString = fs.readFileSync('./db/users.json').toString(); //文件内容变字符串
const usersArray = JSON.parse(usersString); //把字符串变成对应的数组对象
console.log(typeof usersArray); //打印出usersArray数据类型
console.log(usersArray); //打印出usersArray内容
console.log(usersArray instanceof Array); //打印出userArray判定为数组的布尔值
console.log(typeof usersString); //打印出usersString数据类型
console.log(usersString); //打印出usersArray内容
- 读数据库
const fs = require('fs');
const usersString = fs.readFileSync("./db/users.json").toString();
const usersArray = JSON.parse(usersString); //把string变成数组对象,也叫反序列化(反字符串化)
- 写数据库
const user3 = {id:3, name:'tom', password: 'yyy'}
usersArray.push(user3) //把user3放在数组里面
const string = JSON.stringify(usersArray) //把js对象变成string,也叫序列化(字符串化)
fs.writeFileSync('./db/users.json',string) //把字符串存到文件里,路径为第一个参数,变量为第二个参数
这个user3是本地数组,还没有存到数据库,本例中的数据库是user.json文件,而文件只能存字符串的,就需要把新添加的user3变成字符串,然后再写入。
- 示例1:实现用户注册功能
- 用户提交用户名和密码
- users.json里就新增一行数据 5.1 清空users.json数组内容,变成为空数组
5.2 新建register.html文件,更新适配手机的meta viewport标签,引入jQuery,谷歌搜索bootcdn,找到jquery,复制带有min.js的链接,引入以后,可以直接使用jQuery,监听form表单事件
<!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,
minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<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>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
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({
method:'POST', //把数据放在下面,而不是GET方法放在url上
url:'/register',
contentType:'text/json;charset=UTF-8',
data: JSON.stringify({name, password})
})
})
</script>
</body>
</html>
5.3 发请求,发往url:'/register',响应404,因为register不对应任何的文件,所以需要在请求register之前,看一下IE有没有register,也就是提前设置一项路由,并设置Content-Type
if (path ==='/register' && method === "POST"){
response.setHeader('Content-Type','text/html;charset=utf-8')
response.end("很好");
5.4 获取用户上传的name和password,get请求可以用query拿到,post请求用下面的方法:
if (path ==='/register' && method === "POST"){
response.setHeader('Content-Type','text/html;charset=utf-8' )
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
console.log(array)
response.end("很好");
})
}else{
...
5.5 运行test.js,node test.js,得到的结果为utf-8编码,用Buffer.concat(array)合成一个字符串:
<Buffer 7b 22 6e 61 6d 65 22 3a 22 31 32 31 32 33 22 2c 22 70 61 73 73 77 6f 72 64 22 3a 22 31 32 33 31 33 32 22 7d>
if (path ==='/register' && method === "POST"){
response.setHeader('Content-Type','text/html;charset=utf-8' )
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString() //把utf-8编码合成一个字符串
console.log(string)
response.end("很好");
})
}else{
再次执行,得到的结果为:
{"name":"151561","password":"1315614615"}
5.6 把字符串变成对象,最后的代码为:
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' + pathWithQuery)
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)=>{ //监听request的上传事件data
array.push(chunk)
})
request.on('end',()=>{ //结束时,把数组打出来
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
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("很好");
})
}else{
response.statusCode = 200
// 默认首页
const filePath = path === '/' ? '/index.html' : path
const index = filePath.lastIndexOf('.')
// suffix后缀
const suffix = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.png':'image/png',
}
response.setHeader('Content-Type',
`${fileTypes[suffix] ||'text/html'};charset=utf-8`)
let content
try{
content = fs.readFileSync(`./public${filePath}`)
}catch(error){
content = '文件不存在'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)
5.7 用户注册成功之后,跳转到登陆页面:新建一个sign_in.html文件,以下代码实现登陆成功后的动作:
$.ajax({
method:'POST',
url:'/register',
contentType:'text/json;charset=UTF-8',
data: JSON.stringify({name, password})
}).then(()=>{
alert('注册成功')
location.href = '/sign_in.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,
minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<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>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
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({
method:'POST',
url:'/register',
contentType:'text/json;charset=UTF-8',
data: JSON.stringify({name, password})
}).then(()=>{
alert('注册成功')
location.href = '/sign_in.html'
},()=>{})
})
</script>
</body>
</html>
- 示例2:实现用户登陆功能
- 首页home.html,已登陆用户可看到自己用户名
- 登录页sign_in.html,供提交用户名和密码
- 输入的用户名密码如果是匹配的,就自动跳转首页
6.1 新建home.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>Document</title>
</head>
<body>
<p>
你好,{{user.name}}
</p>
<p>
<a href="sign_in.html">登陆</a>
</p>
</body>
</html>
6.2 创建路由:
if (path === 'home.html'){
//暂时写不出
}
6.3 写sign_in.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>
<form id="signInForm">
<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>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
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({
method:'POST',
url:'/sign_in',
contentType:'text/json;charset=UTF-8',
data: JSON.stringify({name, password})
}).then(()=>{
alert('登陆成功')
location.href = '/home.html'
},()=>{})
})
</script>
</body>
</html>