[TOC]
# Express
## 概述
  虽然使用 Node.js 中的 http 模块是可以开发 Web 应用的,处理静态资源,处理动态资源,请求分发(路由)等等,也可以让开发者对 HTTP 协议的理解更加清晰,但是使用起来比较复杂,开发效率低。
  npm 提供了大量的第三方模包,其中不乏许多 Web 框架。Express框架是目前最稳定、使用最广泛,而且 Node.js 官方推荐的唯一一个 Web 开发框架。除了为 http 模块提供了更高层的接口外,还实现了许多功能,其中包括:
* 静态文件服务
* 路由控制
* 模板解析支持
* 动态视图
* 用户会话
* CSRF保护
* 错误控制器
* 访问日志
* 缓存
* 插件支持
## 安装使用
1. 首先创建一个名为 myapp(可自定义) 的目录,在命令行输入并运行 npm init -y。 使用 npm install express 安装 Express 包;
2. 其次在 myapp 目录中,创建一个名为 static.js (可自定义)的文件,并复制下面示例中的代码。
```
const express=require('express');//引入文件
const app = express();//创建对象
app.get('/',(req,res) =>res.send('Hello World'));
app.listen(8888,() =>console.log('启动成功'));
```
使用 node app.js 启动应用,访问 [http://localhost:8888/](http://localhost:8888/) 就可以看到效果。
## 静态资源服务
为了提供访问诸如图片、CSS 文件和 JavaScript 文件之类的静态文件的服务,使用 Express 中的 express.static 函数,格式如下
```
constexpress =require('express');
constpath =require('path');
// 类似昨天我们创建 server
varapp =express();
// 应用静态资源服务的中间件
// static 这个方法返回一个函数,中间件
// 简单静态资源服务
// app.use(express.static(path.join(__dirname,'static')));
// 指定虚拟路径静态资源服务--从路径可以让我们区分访问的资源是静态的还是动态的
app.use('/static',express.static(path.join(__dirname,'static')));
// 针对请求路径/ 且请求方式 get, 就会执行我们下面这个匿名函数
app.get('/',function(req,res){
res.send('你好');
});
// 针对请求路径/ 且请求方式 get, 就会执行我们下面这个匿名函数
app.get('/a',function(req,res){
res.send('你好2');
});
// 绑定端口启动应用
app.listen(8888,() =>{console.log('启动成功');});
```
## 路由
路由指根据不同请求路径和请求方式进行路径分发,导向到不同处理函数,执行不同的业务逻辑。
### 请求方式匹配
HTTP 请求常见的请求方式有 get、post、put、delete 等,Express 支持按请求方式的路由规则。
**app.method**:指定某请求方式的匹配规则;
**app.all**: 指定所有请求方式的匹配规则;
**app.route**: 指定某请求路径的匹配规则;
**app.use**: 应用多个匹配规则;
```
const express =require('express');
const indexRouter =express.Router();
indexRouter.get('/',(req,res) =>{res.send('get index');})// GET/
module.exports =indexRouter;
```
```
const express =require('express');
const userRouter =express.Router();
userRouter.get('/',(req,res) =>{res.send('GET');})// GET/
.post('/',(req,res) =>{res.send('POST');})// POST/
.put('/',(req,res) =>{res.send('PUT');})// PUT/
.delete('',(req,res) =>{res.send('DELETE');});// DELETE/
module.exports =userRouter;
```
```
const express =require('express');
const productRouter = express.Router();
productRouter.get('/',(req,res) =>{res.send('get product');})// GET/
.post('/',(req,res) =>{res.send('post product');})// POST/
.put('/',(req,res) =>{res.send('put product');})// PUT/
.delete('/',(req,res) =>{res.send('delete product');})// DELETE/
.all('/', (req, res) => {res.end('all product');});// ALL
module.exports =productRouter;
```
```
const express = require('express');
const indexRouter = require('./router/index.js');//导入路由
const userRouter = require('./router/user.js');//导入路由
const productRouter = require('./router/product.js');//导入路由
const app = express();
app.use('/abc/index', indexRouter);//应用路由
app.use('/abc/user', userRouter);//应用路由
app.use('/abc/product', productRouter);//应用路由
app.listen(9979,() =>{console.log('启动成功');
});
```
## 请求路径匹配
路由路径可以是字符串、字符串模式或正则表达式。
```
constexpress\=require('express');
constapp\=express();
// GET/
//app.get('/',(req,res)=>{res.send('GET');});
// POST/
//app.get('/',(req,res)=>{res.send('POST');});
// PUT/
//app.get('/',(req,res)=>{res.send('PUT');})
// DELETE/
//app.get('/',(req,res)=>{res.send('DELETE');});
// 链式调用
// GET/
app.get('/',(req,res)\=>{res.send('GET');})
// POST/
.post('/',(req,res)\=>{res.send('POST');})
// PUT/
.put('/',(req,res)\=>{res.send('PUT');})
// DELETE/
.delete('/',(req,res)\=>{res.send('DELETE');})
// ALL
.all('/abc', (req, res) \=> {res.end('ALL');});
app.listen(8886,()\=>{console.log('启动成功');
});
```
## 模块化路由处理程序
使用 express.Router 类来创建可安装的模块化路由处理程序。Router 实例是一个路由系统。
1. router.method :指定某请求方式的匹配规则;
2. router.all :指定所有请求方式的匹配规则
3. router.route :指定某请求路径的匹配规则;
4. router.use :应用多个匹配规则。
**index.js文件代码**
```
// 文件位置:myapp/routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.send('home page');
});
router.get('/about', function(req, res) {
res.send('About us');
});
module.exports = router;
```
**users.js文件代码**
```
// 文件位置:myapp/routes/users.js
const express = require('express');
const router = express.Router();
router.route('/')
.get((req, res) => {
res.send('get user data');
}).post((req, res) => {
res.send('post user data');
}).put((req, res) => {
res.send('put user data');
}).delete((req, res) => {
res.send('delete user data');
});
module.exports = router;
```
**app.js文件代码**
```
// 文件位置:myapp/app.js
const express = require('express');
const app = express();
const index = require('./routes/index'); // 导入路由
const users = require('./routes/users'); // 导入路由
app.use('/', index); // 应用路由
app.use('/users', users); // 应用路由
app.listen(8888, () => {
console.log('running...');
});
```