nodejs入门之Express基础

Express基础

一.前言

基于Node.js平台,快速,开放,极简的Web开发框架

1.框架的作用

框架可以帮助省略掉一些基本的相同底层代码的反复书写,只需调用框架的方法就可以实现你想要的功能。

回顾

nodejs入门之web服务搭建 https://blog.csdn.net/liuqiao0327/article/details/105058145
nodejs入门之get和post请求 https://blog.csdn.net/liuqiao0327/article/details/105086003
这两篇文章。写原生实现总是非常繁琐且费时的。

2.Node相关的框架

  • express

  • koa

  • egg

  • thinkjs

  • adonisjs

  • nestjs

二.Express简介

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求。

  • 定义了路由表用于执行不同的 HTTP 请求动作。

  • 可以通过向模板传递参数来动态渲染 HTML 页面。

三.安装Express

安装 Express 并将其保存到依赖列表中:

$ npm install express

四,使用,搭建一个express的服务

//快速搭建一个基于express框架的web服务
//1. 引入express
const express = require('express');
//2. 生成一个express实例,
const app = express();
//3. 处理各种请求

//处理请求路径localhost:3000/index
app.get('/index', (req, res) => {

    res.send("express 基础");//这里相当于不用框架时的  res.write+ res.end
});
//处理请求路径localhost:3000/details
app.get('/details',(req,res)=>{
    res.send("详情页")
});

//4. 监听3000端口
app.listen(3000, () => {
    console.log("服务启动成功");
});

五.路由

路由是指确定应用程序如何响应客户端(浏览器)对特定端点的请求,该特定端点是URL(或路径)和特定的HTTP请求方式(GET、POST等)。
每个路由可以具有一个或多个处理程序函数,这些函数在路由匹配时执行。

1.路由的基本语法
app.METHOD(PATH,[...HANDLER]) app.get('/index',()=>{})
  • 1.app是express的实例
  • 2.METHOD 是小写的 HTTP 请求方式(GET、POST、PUT、PATCH、DELETE等)。
  • 3.PATH 是请求路径 (以/开头)
  • 4.HANDLER 是当路由匹配时执行的函数。

下面是一些路由,可以使用postman去访问,会有相应的回复

//引入express模块
const express = require('express');
//创建一个express的实例
const app = express();

/**
 * 下面是一些路由
 */
app.get('/', (req, res) => {
    res.send("Get / 响应");
});

app.post('/', (req, res) => {
    res.send("Post / 响应")
});

app.get('/index', (req, res) => {
    res.send("Get index响应");
});

app.get("/details", (req, res) => {
    res.send("Get details响应");
});

app.delete('/delete', (req, res) => {
    res.send("delete 响应");
});

//监听端口
app.listen(3000, () => {
    console.log("服务启动成功");
});
2.请求参数的获取
1.query参数(?号传参)
const express = require('express');

const app = express();

//http://localhost:3000
//这里通过get请求 http://localhost:3000?username=zhangsan&age=18
app.get('/', (req, res) => {
    //http://localhost:3000
    console.log(req.query);//返回一个对象 {}

    //http://localhost:3000?username=zhangsan&age=18
    console.log(req.query);//返回一个对象 { username: 'zhangsan', age: '18' }
    res.send(req.query);
});

app.listen(3000,()=>{
    console.log("服务启动成功");
});
  • Route Path : /
  • Request URL : http://localhost:3000?username=zhangsan&age=18
  • req.query : { name: ‘zhangsan’, age: ‘18’ }
2.body参数 (请求体传参)
注意,req.body需要设置中间件
const express = require('express');

const app = express();
/**
 * 使用req.body的时候,需要调用express.json ()和express.urlencoded()
 * app.use(express.json);
 * app.use(express.urlencoded)
 */

 //处理json格式 的请求体
app.use(express.json());
//处理 x-www-form-xvasdfasdfasdf 这种格式
app.use(express.urlencoded({
    extended:true
}));

app.post('/getBody', (req, res) => {
   //console.log(req.body);//undefined 因为没有设置中间件
    console.log(req.body.username);//设置中间之后可以获取
    console.log(req.body.age);//设置中间之后可以获取
    res.send(req.body);//设置中间之后返回的是对象{ username: 'zhangsan', age: '18' }
});


app.listen(3000, () => {
    console.log("服务启动成功");
});

注意

/**
 * 处理 请求体参数的 解析。
 * Express 4.16.0 起 提供了内置的 express.json() 和 express.urlencoded()
 * 当然他们内部还是基于 bodyParser 的
 */
// app.use(express.json())
// app.use(express.urlencoded({ extended: true }))

这是最新的处理方式

在expresss 4.16.0之前,还是使用的 bodyParser 第三方模块

npm install body-parser
/**
 * 处理 请求体参数的 解析
 * Express 4.16.0 之前使用 bodyParser 第三方模块
 */
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
  • Route Path : /getBody
  • Request URL : http://localhost:3000/getBody
  • Request BODY: username=lisi&password=123456或者 { username: ‘lisi’, password: ‘123456’ }
  • req.body : { username: ‘lisi’, password: ‘123456’ }
3. params 参数(动态路径传参)也就是动态路由
//http://localhost:3000/user/app   app
//http://localhost:3000/user/web   web
//http://localhost:3000/user/moblie moblie

// 冒号后面的可以当做变量  动态路由
app.get('/users/:userRoute', (req, res) => {
    //    我们要想让这三个路径都能进来就要做下区分
    //req.params=>{userRoute:'app'}
    console.log(req.params);
    res.send(req.params);
});

//http://localhost:3000/user/x/app/y
//http://localhost:3000/user/1234/app/34444
//这种长路径,含有变量的
app.get('/user/:userId/app/:bookId', (req, res) => {
    console.log(req.params);
    res.send(req.params); //{ userId: '1234', bookId: '34444' }
});

  • Route Path : /users/:userId/books/:bookId
  • Request URL : http://localhost:3000/users/34/books/8989
  • req.params : { userId: ‘34’, bookId: ‘8989’ }
3.路由处理函数

路由处理函数是一种类似于 中间件函数 的方法。一个路由可以同时设置多个路由处理函数。

路由语法接收三个参数:

  1. req:request 请求对象
  2. res:response 响应对象
  3. next:调用它执行下一个匹配的路由处理函数
// 路由处理函数
/**
 * 回顾路由语法
 * 
 * app.METHOD(path, [...HANDLER])
 * 
 * HANDLER 接收的参数
 *    1. req      请求对象
 *    2. res      响应对象
 *    3. next     是个函数,调用它执行下一个匹配的路由处理函数
 * 
 * HANDLER 是可以有多个的
 */
app.get('/', (req, res, next) => {
    console.log(1);
    next();//必须要写,才可以进入下一个处理函数   
}, (req, res, next) => {
    console.log(2);
    next();
}, (req, res) => {
    console.log(3);
    res.send("执行完毕"); // 1  2  3  
}); 

app.listen(3000,()=>{
    console.log("服务启动成功");
});

上面是多个回调以参数列表的形式组合

// 多个回调,以数组形式
app.get('/index', [(req, res, next) => {
    console.log(1);
    next();//必须要写,才可以进入下一个处理函数   
}, (req, res, next) => {
    console.log(2);
    next();
}, (req, res) => {
    console.log(3);
    res.send("执行完毕");
}]);

上面是多个回调,以数组形式


// 数组与普通的结合
app.get('/hello', [
  (req, res, next) => {
    console.log(1)
    next()
  },

  (req, res, next) => {
    console.log(2)
    next()
  }
], (req, res, next) => {
  console.log(3)
  res.send('hello world')
})

还可以数组与普通的结合

4.express.Router

使用 express.Router 类来创建模块化的,可安装的路由处理程序。一个 Router 实例是一个完整的中间件和路由系统。

思考如下代码:
当项目做大做强时,index.js 文件将异常庞大。不利于后续的项目维护。
比如以下代码:

// index.js
const express = require('express')
const app = express()

app.get('/', (req, res) => { res.send('GET / 响应') })

app.get('/posts', (req, res) => { res.send('GET /posts 响应') })
app.post('/posts', (req, res) => { res.send('POST /posts 响应') })
app.get('/posts/create', (req, res) => { res.send('GET /posts/create 响应') })
app.get('/posts/:id', (req, res) => { res.send('GET /posts/xxid 响应') })
app.put('/posts/:id', (req, res) => { res.send('PUT /posts/xxid 响应') })
app.get('/posts/:id/edit', (req, res) => { res.send('GET /posts/xxid/edit 响应') })
app.delete('/posts/:id', (req, res) => { res.send('DELETE /posts/xxid 响应') })

app.get('/books', (req, res) => { res.send('GET /books 响应') })
app.post('/books', (req, res) => { res.send('POST /books 响应') })
app.get('/books/create', (req, res) => { res.send('GET /books/create 响应') })
app.get('/books/:id', (req, res) => { res.send('GET /books/xxid 响应') })
app.put('/books/:id', (req, res) => { res.send('PUT /books/xxid 响应') })
app.get('/books/:id/edit', (req, res) => { res.send('GET /books/xxid/edit 响应') })
app.delete('/books/:id', (req, res) => { res.send('DELETE /books/xxid 响应') })

app.listen(3000)

这时就可以将相同类别的路由处理代码抽离到单独的文件中,最后在主程序(这里指 index.js)中加载。比如:

1.抽离 posts 相关的存放到 routes/posts.js 文件中

// routes/posts.js
const express = require('express')
const router = express.Router()

router.get('/', (req, res) => { res.send('GET /posts 响应') })
router.post('/', (req, res) => { res.send('POST /posts 响应') })
router.get('/create', (req, res) => { res.send('GET /posts/create 响应') })
router.get('/:id', (req, res) => { res.send('GET /posts/xxid 响应') })
router.put('/:id', (req, res) => { res.send('PUT /posts/xxid 响应') })
router.get('/:id/edit', (req, res) => { res.send('GET /posts/xxid/edit 响应') })
router.delete('/:id', (req, res) => { res.send('DELETE /posts/xxid 响应') })

// 不要忘了暴露出去
module.exports = router

2.抽离 books 相关的存放到 routes/books.js 文件中

// routes/books.js
const express = require('express')
const router = express.Router()

router.get('/', (req, res) => { res.send('GET /books 响应') })
router.post('/', (req, res) => { res.send('POST /books 响应') })
router.get('/create', (req, res) => { res.send('GET /books/create 响应') })
router.get('/:id', (req, res) => { res.send('GET /books/xxid 响应') })
router.put('/:id', (req, res) => { res.send('PUT /books/xxid 响应') })
router.get('/:id/edit', (req, res) => { res.send('GET /books/xxid/edit 响应') })
router.delete('/:id', (req, res) => { res.send('DELETE /books/xxid 响应') })

// 不要忘了暴露出去
module.exports = router

3.在主程序中(index.js)中引入并使用

// index.js
const express = require('express')

// 引入
const postsRouter = require('./routes/posts.js')
const booksRouter = require('./routes/books.js')

const app = express()

app.get('/', (req, res) => { res.send('GET / 响应') })

// 使用
app.use('/posts', postsRouter)
app.use('/books', booksRouter)

app.listen(3000)
发布了17 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/liuqiao0327/article/details/105109017