express

  1. express介绍

  1. 概念:express就是基于nodejs封装的一个框架,专业用于提供方便易操作的web服务器。

  1. 下载安装:

  1. npm init -y npm i express -S

  1. 使用步骤:

  1. 导入包

  1. 创建服务器

  1. 处理请求

  1. 监听端口

  1. const express = require('express') const app = express() app.listen(端口号)

  1. 路由

  1. 路由方法
语法:
app.路由方法(路径, 处理函数)
// 例子
app.get('/', (req, res) => {
    res.end('heihei')
})

路由方法包括:
  1. get:请求方式是get的,且请求路径为参数1的,可以处理,只能处理一次

const express = require('express')
const app = express()
app.listen(3000)

app.get('/', (req, res) => {
    res.end('heihei')
})

app.get('/', (req, res) => {
    res.end('haha')
})

页面只显示heihei

  1. post:请求方式是post的,且请求路径为参数1的,可以处理,只能处理一次

表单页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单页面</title>
</head>
<body>
    <form method='post' action="/postSubmit">
        账号:<input type="text" name="account" />
        <br>
        密码:<input type="password" name="password" />
        <br>
        <input type="submit" />
    </form>
</body>
</html>

js代码

const express = require('express')
const app = express()
app.listen(3000)

app.get('/', (req, res) => {
    res.end(require('fs').readFileSync('./form.html'))
})

app.post('/postSubmit', (req, res) => {
    res.end('haha')
})

  1. put:请求方式是put的,且请求路径为参数1的,可以处理,只能处理一次

const express = require('express')
const app = express()
app.listen(3000)

app.put('/', (req, res) => {
    res.end('this is put request"s response')
})

  1. delete:请求方式是delete的,且请求路径为参数1的,可以处理,只能处理一次

const express = require('express')
const app = express()
app.listen(3000)
app.delete('/', (req, res) => {
    res.end('this is delete request"s response')
})

  1. all:任意请求方法都可以处理,且请求路径为参数1的,都可以处理,只能处理一次

const express = require('express')
const app = express()
app.listen(3000)

app.all('/', (req, res) => {
    res.end('this is all request"s response')
})

  1. use:任意请求方法都可以处理,且请求路径以参数1开头的,都可以处理,可以处理多次。可以省略参数1,表示任意路径的请求都会被处理。

处理路径开头的请求:

const express = require('express')
const app = express()
app.listen(3000)

app.use('/a', (req, res) => {
    res.end('use method handle request that the path startsWith "/a"')
})

处理多次:

const express = require('express')
const app = express()
app.listen(3000)

app.use('/', (req, res, next) => {
    console.log('第一次处理');
    next()
})

app.get('/', (req, res) => {
    console.log('第二次处理');
    res.end('use method handle many requests')
})

处理请求的函数中,可以添加第三个参数next,调用next,表示这次处理结束后,会继续向下执行,再次匹配到后,会再次处理:

  1. 路由匹配
  • 完全匹配

请求的路径必须跟定义好的路径完全相等,才会处理:

// 匹配根路径的请求
app.get('/', function (req, res) {
  res.send('root');
});

// 匹配 /about 路径的请求
app.get('/about', function (req, res) {
  res.send('about');
});

// 匹配 /random.text 路径的请求
app.get('/random.text', function (req, res) {
  res.send('random.text');
});
  • 不完全匹配

请求路径能符合定义好的路径的规则即可处理:

// 匹配 acd 和 abcd
app.get('/ab?cd', function(req, res) {
  res.send('ab?cd');
});

// 匹配 abcd、abbcd、abbbcd等
app.get('/ab+cd', function(req, res) {
  res.send('ab+cd');
});

// 匹配 abcd、abxcd、abRABDOMcd、ab123cd等
app.get('/ab*cd', function(req, res) {
  res.send('ab*cd');
});

// 匹配 /abe 和 /abcde
app.get('/ab(cd)?e', function(req, res) {
 res.send('ab(cd)?e');
});
  • 正则匹配

请求的路径能符合定义好的正则规则就可以处理:

// 匹配任何路径中含有 a 的路径:
app.get(/a/, function(req, res) {
  res.send('/a/');
});

// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等
app.get(/.*fly$/, function(req, res) {
  res.send('/.*fly$/');
});
  • restful风格匹配

传统方式:http://localhost:3000/index.html?id=6&name=zhangsan

动态路由:http://localhost:3000/index.html/6/zhangsan

app.get('/about/:id', function (req, res) {
  res.send('about');
});

表示在请求的时候,/about后面必须加一个id才可以匹配成功去处理。

app.get('/about/:id?', function (req, res) {
  res.send('about');
});

若要表示id可选项的话,使用?:

传统方式的路径参数获取,使用req.query

例如:请求地址 - http://localhost:3000/index.html?id=6&name=zhangsan

const express = require('express')
const app = express()
app.listen(3000)

app.get('/index.html', (req, res) => {
    console.log(req.query);
    res.end('get method"s params')
})

动态路由传参的获取,使用req.params

例如:请求地址 - http://localhost:3000/index.html/6/zhangsan

const express = require('express')
const app = express()
app.listen(3000)

app.get('/index.html/:id/:name', (req, res) => {
    console.log(req.params);
    res.end('get method"s params')
})

  1. 路由处理
  1. 单函数处理

app.get('/home', function (req, res) {
  res.end('home');
});
  1. 多函数处理

app.get('/home', function (req, res, next) {
  console.log('这处理完之后会交给下一个函数处理');
  next();
}, function (req, res) {
  res.end('home');
});

多个函数处理同一个请求的时候,多个函数共用同一个req,例:

app.get('/home', function (req, res, next) {
    req.num = 6
      console.log('这处理完之后会交给下一个函数处理');
      next();
}, function (req, res) {
    console.log(req.num)
      res.end('home');
});
  1. 函数数组处理

var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

var cb2 = function (req, res) {
  res.end('home')
}

app.get('/home', [cb0, cb1, cb2])
  1. 函数数组处理

var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

app.get('/home', [cb0, cb1], function (req, res, next) {
  console.log('CB')
  next()
}, function (req, res){
  res.end('home')
})
  1. 路由对象配合use处理路由

use配合路由对象处理路由的时候,会将自己匹配到的路径截取掉,给router就剩下截取后剩下的路径

const express = require('express')
const app = express()
const router = expresss.Router()
app.use('/user', router)
router.get('/add', (req, res) => {
    res.end('/user/add')
})
  1. 路由模块化

利用use方法和router的配合,我们可以将某一部分的请求单独封装到一个文件中,例如,所有有关用户的请求,都会是/user开头的请求路径,将所有有关用户请求的路由处理,单独封装在一个文件中。

app.js

const express = require('express')
const app = express()
const userRouter = require('./user')
app.use('/user', userRouter)
const goodsRouter = require('./goods')
app.use('/goods', goodsRouter)
app.listen(12345)

user.js

const express = require('express')
const router = express.Router()
router.get('/add', (req, res) => {
    res.end('/user/add')
})
router.get('/edit', (req, res) => {
    res.end('/user/edit')
})
module.exports = router

goods.js

const express = require('express')
const router = express.Router()
router.get('/add', (req, res) => {
    res.end('/goods/add')
})
router.get('/edit', (req, res) => {
    res.end('/goods/edit')
})
module.exports = router
  1. 响应方法

res.end() // 终结响应处理流程。
res.redirect() // 重定向请求。
res.send() // 发送各种类型的响应。
res.sendFile() // 以八位字节流的形式发送文件。
res.sendStatus() // 设置响应状态代码,并将其以字符串形式作为响应体的一部分发送。
res.json()

  1. 中间件

  1. 中间件的分类
  1. 内置中间件 - express系统自带

  1. 自定义中间件 - 自己开发的中间件

  1. 第三方中间件 - 有人开发好了,我们下载下来使用

根据中间件的使用情况,可以将中间件分为2类:

  1. 应用级别中间件 - 由app调用的

  • 全局应用级别中间件 - 当前路由后面的所有请求都会经过这个中间件

  • 局部应用级别中间件 - 只在当前路由中有效

  1. 路由级别中间件 - 由router调用的

  • 全局路由级别中间件

  • 局部路由级别中间件

  1. 中间件语法
  1. 应用级别使用:

app.use(中间件函数)
  1. 路由级别使用:

router.use(中间件函数)

上面两种使用都是全局的,表示他们后面的路由处理都要经过这个中间件

  1. 内置中间件
  1. 静态资源服务器中间件
  1. 静态资源服务器中间件:express.static() - 必须是全局中间件

app.use(express.static('托管目录地址')) 
  1. 此时我们可以通过/静态资源名称就能访问到指定文件夹中的静态资源

  1. 为了方便区分静态资源路径和其他请求的处理,可以指定请求静态资源的时候,使用指定的路径前缀,此时我们可以通过/前缀/静态资源名称来访问到指定文件夹的静态资源。

  1. app.use('前缀',express.static('托管目录地址'))

app.use('前缀',express.static('托管目录地址'))
  1. 获取post请求传递的请求主体:express.urlencoded() - 可全局可局部
app.use(express.urlencoded({extended: false}))

此后的post请求都可以通过req.body获取到post请求传递的请求主体了。

  1. 自定义中间件

概念:自定义中间件,本质上是一个函数,相当有我们使用多个函数处理请求的时候,中间经历的函数。

自定义中间件:

function myMiddleware(req,res,next){    
    //. 自己需要定义的逻辑流程
    // 中间件最后一定要执行此函数,否则程序无法向下执行下去
    next()
}

使用:

app.use(myMiddleware) // 全局应用级别中间件
app.get(路径, myMiddleware, (req, res) => {}) // 局部应用级别中间件

router.use(myMiddleware) // 全局路由级别中间件
router.post(路径, myMiddleware, (req, res) => {}) // 局部路由级别中间件
  1. 第三方中间件

body-parser这个中间件的功能是用来获取post请求传递的请求主体的

使用方法
  1. 下载:

npm i body-parser
  1. 导入

const bodyParser = require('body-parser')
  1. 使用中间件

app.use(bodyParser.urlencoded({extended: false}))
  1. 异常处理中间件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值