一. Express初体验1.1. 认识Web框架
前面我们已经学习了使用http内置模块来搭建Web服务器,为什么还要使用框架?
目前在Node中比较流行的Web服务器框架是express、koa;
express早于koa出现,并且在Node社区中迅速流行起来:
1.2. express的安装
express的使用过程有两种方式:
方式一:安装express-generator
npm install -g express-generator
创建项目:
express express-demo
项目目录如下:
├── app.js
├── bin
│ └── www
├── package-lock.json
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
我们可以安装依赖,将程序跑起来:
npm install
node bin/www
方式二:从零学习搭建
刚才创建的项目express项目,很多内容可能我们并不认识,所以刚开始我们最好从零来学习。
初始化一个新的项目
npm init -y
express的安装:
npm install express
1.3. express初体验
我们来创建自己的第一个express程序:
const express = require('express');
// 创建服务器
const app = express();
// /home的get请求处理
app.get("/home", (req, res) => {
res.end("Hello Home");
});
// /login的post请求处理
app.post("/login", (req, res) => {
res.end("Hello Login");
});
// 开启监听
app.listen(8000, () => {
console.log("服务器启动成功~");
})
我们会发现,之后的开发过程中,可以方便的将请求进行分离:
当然,这只是初体验,接下来我们来探索更多的用法;
1.4. 请求和响应
请求的路径中如果有一些参数,可以这样表达:
返回数据,我们可以方便的使用json:
const express = require('express');
const app = express();
app.get('/users/:userId', (req, res, next) => {
console.log(req.params.userId);
res.json({username: "coderwhy", level: 99});
});
app.listen(8000, () => {
console.log("静态服务器启动成功~");
})
二. Express中间件2.1. 认识中间件
Express是一个路由和中间件的Web框架,它本身的功能非常少:
中间件是什么呢?
中间件中可以执行哪些任务呢?
如果当前中间件功能没有结束请求-响应周期js上传图片到项目服务器上,则必须调用next()将控制权传递给下一个中间件功能,否则js上传图片到项目服务器上,请求将被挂起。
中间件函数调用的元素:
image-202011012053338432.2. 应用中间件
那么,如何将一个中间件应用到我们的应用程序中呢?
我们先来学习use的用法,因为methods的方式本质是use的特殊情况;
案例一:最普通的中间件
之所以称之为最普通的中间件,是因为无论是什么path、methods都会应用该中间件;
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log("common middleware 01");
next();
})
app.use((req, res, next) => {
console.log("common middleware 02");
res.end("Hello Common Middleware~");
})
app.listen(8000, () => {
console.log("中间件服务器启动成功~");
})
中间件的执行顺序:
案例二:path匹配中间件
如果我们希望匹配一个明确的路径,也可以使用use方法:
// 案例二: 路径匹配中间件
app.use('/home', (req, res, next) => {
console.log("home middleware 01");
next();
});
app.use('/home', (req, res, next) => {
console.log("home middleware 02");
next();
res.end("Hello Home middleware");
});
app.use((req, res, next) => {
console.log("common middleware");
});
案例三:path和method匹配中间件
// 案例三: method匹配中间件
app.get('/home', (req, res, next) => {
console.log("home get middleware");
next();
})
app.post('/login', (req, res, next) => {
console.log("login post middleware");
next();
});
app.use((req, res, next) => {
console.log("common middleware");
});
案例四:注册多个中间件
// 案例四: 注册多个中间件
const homeMiddleware1 = (req, res, next) => {
console.log('home middleware 01');
next();
}
const homeMiddleware2 = (req, res, next) => {
console.log('home middleware 02');
next();
}
const homeHandle = (req, res, next) => {
res.end("Hello Home~");
}
app.get('/home', homeMiddleware1, homeMiddleware2, homeHandle);
2.3. 应用其他中间件
并非所有的中间件都需要我们从零去编写:
2.3.1. request解析中间件
在客户端发送post请求时,会将数据放到body中:
我们这里先使用json传递给服务器body:
json传递body
不进行解析时的操作:
app.post('/login', (req, res, next) => {
req.on('data', (data) => {
console.log(data.toString());
})
req.on('end', () => {
res.end("登录成功~");
});
});
我们也可以自己编写中间件来解析JSON:
app.use((req, res, next) => {
if (req.headers['content-type'] === 'application/json') {
req.on('data', (data) => {
const userInfo = JSON.parse(data.toString());
req.body = userInfo;
})
req.on('end', () => {
next();
})
} else {
next();
}
})
app.post('/login', (req, res, next) => {
console.log(req.body);
res.end("登录成功~");
});
但是,事实上我们可以使用expres内置的中间件或者使用body-parser来完成:
app.use(express.json());
app.post('/login', (req, res, next) => {
console.log(req.body);
res.end("登录成功~");
});
如果我们解析的是 application/x-www-form-urlencoded:
form传递body
我们可以使用express自带的 urlencoded函数来作为中间件:
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.post('/login', (req, res, next) => {
console.log(req.body);
res.end("登录成功~");
});
2.3.2. 日志记录中间件
如果我们希望将请求日志记录下来,那么可以使用express官网开发的第三方库:morgan
安装morgan:
npm install morgan
直接作为中间件使用即可:
const loggerWriter = fs.createWriteStream('./log/access.log', {
flags: 'a+'
})
app.use(morgan('combined', {stream: loggerWriter}));
2.3.3. 上传文件中间件
图片上传我们可以使用express官方开发的第三方库:multer
npm install multer
上传文件,并且默认文件名:
const upload = multer({
dest: "uploads/"
})
app.post('/upload', upload.single('file'), (req, res, next) => {
console.log(req.file.buffer);
res.end("文件上传成功~");
})
添加文件名后缀:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/")
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname));
}
})
const upload = multer({
storage
})
app.post('/upload', upload.single('file'), (req, res, next) => {
console.log(req.file.buffer);
res.end("文件上传成功~");
})
我们也可以上传多张图片:
app.use('/upload', upload.array('files'), (req, res, next) => {
console.log(req.files);
});
如果我们希望借助于multer帮助我们解析一些form-data中的普通数据,那么我们可以使用any:
image-20201104165039444
app.use(upload.any());
app.use('/login', (req, res, next) => {
console.log(req.body);
});
2.4. 请求和响应
客户端传递到服务器参数的方法常见的是5种:
2.4.1. 请求解析
方式一:params
请求地址::8000/login/abc/why
获取参数:
app.use('/login/:id/:name', (req, res, next) => {
console.log(req.params);
res.json("请求成功~");
})
方式二:query
请求地址::8000/login?username=why&password=123
获取参数:
app.use('/login', (req, res, next) => {
console.log(req.query);
res.json("请求成功~");
})
2.4.2. 响应方式
end方法
版权声明
本文仅代表作者观点。
本文系作者授权发表,未经许可,不得转载。
发表评论