node
November 08, 2023
11214
一、node.js
(一)创建web服务器
具体代码
1
2
3
4
5
6
7
8
9
10
11
12const http = require('http'); // 1.引用http系统模块
const app = http.createServer() ; //2. 创建web服务器
//3.监听浏览器的请求
app.on('request', (req, res) => {
res.end('<h1>hi, user</h1>'); // req 请求对象 res响应对象
});
//4.启动服务绑定端口
app.listen(3100, () => { console.log('启动成功'); });
简写:
require('http').createServer().on('request', (req, res) => { res.end('hello world')}).listen(4000)
(二) HTTP协议
请求报文
1
2
3
4
5app.on('request', (req, res) => {
req.headers // 获取请求报文
req.url // 获取请求地址
req.method // 获取请求方法
});响应报文
1
2
3
4
5
6app.on('request', (req, res) => {
// 设置响应报文
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf8‘
});
});
(三)、HTTP请求与响应处理
get请求参数
1
2
3
4
5
6
7
8
9
10const http = require('http');
// 导入url系统模块 用于处理url地址
const url = require('url');
const app = http.createServer();
app.on('request', (req, res) => {
// 将url路径的各个部分解析出来并返回对象
// true 代表将参数解析为对象格式
let { query, pathname } = url.parse(req.url, true);
});
app.listen(3000);post请求参数
1
2
3
4
5
6
7
8
9
10
11// 导入系统模块querystring 用于将HTTP参数转换为对象格式
const querystring = require('querystring');
app.on('request', (req, res) => {
let str = '';
// 监听参数传输事件
req.on('data', (chunk) => str += chunk;);
// 监听参数传输完毕事件
req.on('end', () => {
console.log(querystring.parse(str));
});
});路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44// 引入router模块
const getRouter = require('router');
// 获取路由对象
const router = getRouter();
// 学生信息集合
const Student = require('../model/user');
// 引入模板引擎
const template = require('art-template');
// 引入querystring模块
const querystring = require('querystring');
// 呈递学生档案信息页面
router.get('/add', (req, res) => {
let html = template('index.art', {});
res.end(html);
})
// 呈递学生档案信息列表页面
router.get('/list', async (req, res) =>{
// 查询学生信息
let students = await Student.find();
console.log(students);
let html = template('list.art', {
students: students
})
res.end(html)
})
// 实现学生信息添加功能路由
router.post('/add', (req, res) => {
// 接收post请求参数
let formData = '';
req.on('data', param => {
formData += param;
});
req.on('end', async () => {
await Student.create(querystring.parse(formData))
res.writeHead(301, {
Location: '/list'
});
res.end()
})
});
module.exports = router;
二、Express框架
(一)创建
具体使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52// 引入express框架
const express = require('express');
const fs = require('fs');
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
// 创建网站服务器
const app = express();
app.get('/request' , (req, res, next) => {
// send()
// 1. send方法内部会检测响应内容的类型
// 2. send方法会自动设置http状态码
// 3. send方法会帮我们自动设置响应的内容类型及编码
req.name = "张三";
res.send('Hello. Express');
})
// 当客户端访问/admin请求的时候走当前中间件
app.use('/admin', (err, req, res, next) => {
// 用户没有登录
let isLogin = true;
// 如果用户登录
if (isLogin) {
// 让请求继续向下执行
next()
}else {
// 如果用户没有登录 直接对客户端做出响应
res.send('您还没有登录 不能访问/admin这个页面')
// 或者
// 为客户端响应404状态码以及提示信息
res.status(404).send('您还没有登录 不能访问/admin这个页面')
}
res.status(500).send(err.message);
})
app.get('/index', async (req, res, next) => {
try {
await readFile('./aaa.js')
}catch (ex) {
next(ex);
}
})
// 接收所有请求的中间件 错误处理中间
app.use((err, req, res, next) => {
res.status(500).send(err.message);
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 引入express框架
const express = require('express');
// 创建网站服务器
const app = express();
// 创建路由对象
const home = express.Router();
const admin = require('./route/admin');
// 为路由对象匹配请求路径
app.use('/home', home);
app.use('/admin', admin);
// 创建二级路由
home.get('/index', (req, res) => {
res.send('欢迎来到博客首页页面')
})
// 端口监听
app.listen(3000);请求参数处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 引入express框架
const express = require('express');
const bodyParser = require('body-parser');
// 创建网站服务器
const app = express();
// 拦截所有请求
// extended: false 方法内部使用querystring模块处理请求参数的格式
// extended: true 方法内部使用第三方模块qs处理请求参数的格式
app.use(bodyParser.urlencoded({extended: false}))
app.post('/add', (req, res) => {
// 接收post请求参数
res.send(req.body)
})
app.get('/index/:id/:name/:age', (req, res) => {
// 接收post请求参数
res.send(req.params)
})
// 端口监听
app.listen(3000);实现静态资源访问功能
1
2
3
4
5
6
7
8
9const express = require('express');
const path = require('path');
const app = express();
// 实现静态资源访问功能
app.use('/static',express.static(path.join(__dirname, 'public')))
// 端口监听
app.listen(3000);模板引擎artTemplate(第三方模块)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33const express = require('express');
const path = require('path');
const app = express();
// 模板配置
// 1.告诉express框架使用什么模板引擎渲染什么后缀的模板文件
// 1.模板后缀
// 2.使用的模板名
app.engine('art', require('express-art-template'))
// 2.告诉express框架模板存放的位置是什么
app.set('views', path.join(__dirname, 'views'))
// 3.告诉express框架模板的默认后缀是什么
app.set('view engine', 'art');
app.get('/index', (req, res) => {
// 1. 拼接模板路径
// 2. 拼接模板后缀
// 3. 哪一个模板和哪一个数据进行拼接
// 4. 将拼接结果响应给了客户端
res.render('index', {
msg: 'message'
})
});
app.get('/list', (req, res) => {
res.render('list', {
msg: 'list page'
})
})
// 端口监听
app.listen(3000);
(二)使用
数据库连接
1
2
3
4
5
6// 引入mongoose第三方模块
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/blog', {useNewUrlParser: true })
.then(() => console.log('数据库连接成功'))
.catch(() => console.log('数据库连接失败'))创建用户集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76// 创建用户集合
// 引入mongoose第三方模块
const mongoose = require('mongoose');
// 导入bcrypt
const bcrypt = require('bcrypt');
// 引入joi模块
const Joi = require('joi');
// 创建用户集合规则
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
minlength: 2,
maxlength: 20
},
email: {
type: String,
// 保证邮箱地址在插入数据库时不重复
unique: true,
required: true
},
password: {
type: String,
required: true
},
// admin 超级管理员
// normal 普通用户
role: {
type: String,
required: true
},
// 0 启用状态
// 1 禁用状态
state: {
type: Number,
default: 0
}
});
// 创建集合
const User = mongoose.model('User', userSchema);
async function createUser () {
const salt = await bcrypt.genSalt(10);
const pass = await bcrypt.hash('123456', salt);
const user = await User.create({
username: 'iteheima',
email: 'itheima@itcast.cn',
password: pass,
role: 'admin',
state: 0
});
}
// createUser();
// 验证用户信息
const validateUser = user => {
// 定义对象的验证规则
const schema = {
username: Joi.string().min(2).max(12).required().error(new Error('用户名不符合验证规则')),
email: Joi.string().email().required().error(new Error('邮箱格式不符合要求')),
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/).required().error(new Error('密码格式不符合要求')),
role: Joi.string().valid('normal', 'admin').required().error(new Error('角色值非法')),
state: Joi.number().valid(0, 1).required().error(new Error('状态值非法'))
};
// 实施验证
return Joi.validate(user, schema);
}
// 将用户集合做为模块成员进行导出
module.exports = {
User,
validateUser
}完整的接口内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38// 导入用户集合构造函数
const { User } = require('../../model/user');
const bcrypt = require('bcrypt');
module.exports = async (req, res) => {
// 接收请求参数
const {email, password} = req.body;
// 如果用户没有输入邮件地址
// if (email.trim().length == 0 || password.trim().length == 0) return res.status(400).send('<h4>邮件地址或者密码错误</h4>');
if (email.trim().length == 0 || password.trim().length == 0) return res.status(400).render('admin/error', {msg: '邮件地址或者密码错误'});
// 根据邮箱地址查询用户信息
// 如果查询到了用户 user变量的值是对象类型 对象中存储的是用户信息
// 如果没有查询到用户 user变量为空
let user = await User.findOne({email});
// 查询到了用户
if (user) {
// 将客户端传递过来的密码和用户信息中的密码进行比对
// true 比对成功
// false 对比失败
let isValid = await bcrypt.compare(password, user.password);
// 如果密码比对成功
if ( isValid ) {
// 登录成功
// 将用户名存储在请求对象中
req.session.username = user.username;
// res.send('登录成功');
req.app.locals.userInfo = user;
// 重定向到用户列表页面
res.redirect('/admin/user');
} else {
// 没有查询到用户
res.status(400).render('admin/error', {msg: '邮箱地址或者密码错误'})
}
} else {
// 没有查询到用户
res.status(400).render('admin/error', {msg: '邮箱地址或者密码错误'})
}
}入口文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54// 引用expess框架
const express = require('express');
// 处理路径
const path = require('path');
// 引入body-parser模块 用来处理post请求参数
const bodyPaser = require('body-parser');
// 导入express-session模块
const session = require('express-session');
// 创建网站服务器
const app = express();
// 数据库连接
require('./model/connect');
// 处理post请求参数
app.use(bodyPaser.urlencoded({extended: false}));
// 配置session
app.use(session({
secret: 'secret key',
saveUninitialized: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000
}
}));
// 告诉express框架模板所在的位置
app.set('views', path.join(__dirname, 'views'));
// 告诉express框架模板的默认后缀是什么
app.set('view engine', 'art');
// 当渲染后缀为art的模板时 所使用的模板引擎是什么
app.engine('art', require('express-art-template'));
// 开放静态资源文件
app.use(express.static(path.join(__dirname, 'public')))
// 引入路由模块
const home = require('./route/home');
const admin = require('./route/admin');
// 拦截请求 判断用户登录状态
app.use('/admin', require('./middleware/loginGuard'));
// 为路由匹配请求路径
app.use('/home', home);
app.use('/admin', admin);
app.use((err, req, res, next) => {
// 将字符串对象转换为对象类型
// JSON.parse()
const result = JSON.parse(err);
res.redirect(`${result.path}?message=${result.message}`);
})
// 监听端口
app.listen(80);
console.log('网站服务器启动成功, 请访问localhost')
- 本文作者:wowangmouren
- 本文链接:https://wangwewntao.top/2023/11/08/wmr_18/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!