后端:把Express给他,自己造接口去

732 阅读7分钟

前言

这篇文章的诞生源于我之前的一个经历,我有一个比较好的点子,想把它实现出来,但是无奈自己只能写前端的部分,后端的接口却无从下手,学习JAVAGo等周期又太长了;后面了解到了这个框架,对前端来说上手很自然,通过和MongoDB数据库结合解决了我的后端需要;所以写这篇express入门的文章也是为了解决和我之前遇到同样问题的朋友。

介绍

首先这里是它的官网(点不开就进这个中文网站

image.png

Express是一个基于Node.js平台,快速、开放、极简的Web开发框架:

  • Web应用程序:Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能
  • API:使用您所选择的各种 HTTP 实用工具和中间件,快速方便地创建强大的 API
  • 性能:Express 提供精简的基本 Web 应用程序功能,而不会隐藏您了解和青睐的 Node.js 功能
  • 框架:许多 流行的开发框架 都基于 Express 构建

基本使用

开始之前,请先在一个文件夹中,使用npm init初始化项目,下载express包,后续的操作都在这个文件夹中进行

Web服务

新建一个index.js作为主文件

// 引入express
const express = require('express');

// 执行express
const app = express();


// 编写接口
app.get('/', (req, res, next) => {
  // res.write('111');
  // res.end();
  // res.send = res.write+res.end
  // res.send('111');
  res.send(`
      <html>
          <h1>111</h1>
      </html>
  `);
});

// 监听3000端口
app.listen(3000, () => {
  console.log('server start');
});


node index.js执行上面文件,那么在http://localhost:3000/根目录就能够看到页面内容:(此处将以上文件定义为入口文件)

image.png

这里要讲一下,上方代码中的API:

  • get:编写一个get请求的接口
  • get中第二个参数中的形参:
    • res:请求相关内容(请求参数、请求地址、请求头等)
    • req:相应相关内容(响应头设置、响应内容设置等)
    • next(可选):如果有多个中间件时,可以调用 next() 传递到下一个中间件
  • listen:监听端口

路由

经过上面的操作之后,页面内容显示了出来,但是只有一个页面,挺单调的;这里使用express.Router来增加一个home页面.

在根目录新建router文件夹,然后在文件夹中新建js文件,命名为HomeRouter,写入以下内容:

const express = require('express');

const router = express.Router();

router.get('/', (req, res) => {
  res.send('home 页面内容');
});

module.exports = router;

在入口文件引入它:

const HomeRouter = require('./router/HomeRouter');
...

app.use('/home', HomeRouter);

...

重新运行之后,访问/home,就能看到如下内容:

image.png


除了显示页面内容,也可以在router中定义接口内容,比如这里我们在上面的HomeRouter文件中加入一个get接口:

router.get('/data', (req, res) => {
  res.send([1, 2, 3]);
});

这时候访问/home/data,就有以下效果:

image.png

也就是说,router的功能既可以定义返回页面内容的接口,也可以定义返回数据的接口。

后续若是你真正的使用,可能会有userRouterLoginRouter等等代表不同的接口,这时候router文件夹就起到了集中统一管理的作用:

image.png

模版

到了这一步,你可能对于上面的直接返回页面内容有了疑问:以后复杂的页面不可能都用这种方式返回页面内容吧?

是的,你的感觉是对的,肯定不可能这样使用;所以接下来,就要引出EJS模版这个概念了。

EJS是一个用于Web开发的JavaScript模板引擎,允许用户使用HTML模板中的JavaScript代码生成动态HTML标记。

接下来,我们将上方的例子改造一下:

  1. 在这里先引入ejs包:
npm install ejs
  1. 在根目录创建文件夹views统一管理页面,在文件夹中创建两个文件:home.ejslogin.ejs

image.png

// home.ejs
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    // 语法 <%= 值%>
    home 传入的值 <%= data%>
  </body>
</html>

// login.ejs
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    login-html
    // 语法 <%= 值%>
    <h1>传入的值:<%=title%></h1>
    <form action="/login" method="post">
      <div>用户名:<input type="text" name="username" /></div>
      <div>密码:<input type="password" name="password" /></div>
      <div><input type="submit" value="登录" /></div>
    </form>
  </body>
</html>

  1. 修改HomeRouter,新增LoginRouter
// HomeRouter
const express = require('express');

const router = express.Router();

router.get('/', (req, res) => {
  // 渲染模版,并给模版传参
  res.render('home', {data: 222}); // 找views文件夹下的home.ejs
});

module.exports = router;

// LoginRouter
const express = require('express');

const router = express.Router();

// 路由级别-响应前端的给请求
router.get('/', (req, res) => {
  console.log(req.query, 'req');
  // res.send('login根');
  // 渲染模版,并给模版传参
  res.render('login', {title: 222}); // 找views文件夹下的login.ejs
});

// 路由级别-响应前端的post请求
router.post('/', (req, res) => {
  res.redirect('/home');
});

module.exports = router;

  1. 入口文件修改为如下内容:
const express = require('express');
const LoginRouter = require('./router/LoginRouter');
const HomeRouter = require('./router/HomeRouter');

const app = express();

// 配置模版引擎
app.set('views', './views');
app.set('view engine', 'ejs');

app.use('/login', LoginRouter);
app.use('/home', HomeRouter);

app.listen(3000, () => {
  console.log('启动');
});

经过以上修改之后,访问/home就是home.ejs的内容,访问/login就是login.ejs的内容:

image.png

image.png


ok,效果出来了,梳理一下模版使用的知识点,如下:

express使用ejs的步骤:

  • 引入ejs包
  • 入口文件配置ejs
  • router中使用res.render渲染ejs

路由传参

经过上面的例子,能够做到显示不同的页面了;在login页面中,可以看到留了一个登录表单,LoginRouter也预留了一个post请求。没错,这一节要来讲一下路由传参(bodyquery)了,正好从获取post参数开始讲。

配置解析请求体,在入口文件加入以下内容:

// 配置解析body参数(4.16.0 及以上的版本)
app.use(express.urlencoded({extended: false}));
app.use(express.json()); // json格式

LoginRouter中的post接口中,添加一行代码:

console.log(req.body);

重新运行,输入帐号、密码,点击登录,在终端即可看到以下内容:

[Object: null prototype] { username: '111', password: '222' }

ok,获取query参数就更简单了,不用配置,直接res.query就可以查看内容;在HomeRouter中添加一行代码:

console.log(req.query);

重新运行之后,访问这个地址http://localhost:3000/home?abc=111

终端就会出现以下内容:

{ abc: '111' }

那么,总结一下:

  • 请求体参数:需要在主入口配置以下内容后,在req.body中获取到

    app.use(express.urlencoded({extended: false}));
    app.use(express.json());
    
  • query参数:无需配置,在req.query中获取到

中间件

在 Express 中,中间件(Middleware)是函数,用于处理请求和响应对象。在请求-响应周期中,中间件可以访问请求对象 (req)、响应对象 (res),以及下一个中间件函数,通过调用 next() 来传递控制权。

中间件主要有以下几种类型:

  • 应用级中间件
  • 路由级中间件
  • 内置中间件
  • 第三方中间件

中间件主要是用来处理一些系统层面的事情,例如登录校验、统一错误处理等等。

在主入口文件的头部位置,加入以下代码:

app.use((req, res, next) => {
  console.log('应用级中间件');
  next();
});

// 加了路径代表只有这个路径才执行
app.use('/home', (req, res, next) => {
  console.log('路由级中间件');
  next();
});

现在访问接口的时候,应用级中间件会触发,访问/home的时候会同时触发应用级中间件和路由级中间件:

应用级中间件
路由级中间件

总结:中间件是express的核心概念,能够处理一些系统层面的工作,然后将控制权交出去。

静态资源

express提供了express.static的方式来配置静态文件,例如:

app.use(express.static('public'));

访问的时候,不需要public,只需要localhost:3000/文件名,就能够访问到。

总结

到这里的话,express的基本概念就讲解完毕了,文中带着你写了访问页面的接口、返回数据的接口、请求参数获取、路由分块等等功能;

你可以用它来写前后端一体的项目,也可以按标题说的作为一个后端来给你自己提供接口,写一点自己的东西。如果你有数据库需要的话,express也可以和MongoDB结合(有MongoDB的需要,推荐一下这一篇《入门MongoDB,看这一篇文章就够了》);如果你有登录校验的需要,还可以JWTexpress结合。

总之express能做的事情还是很多的,是一个挺不错的框架,如果你对它的底层原理感兴趣的话,可以去研究一下Node.jshttp模块。

ok,感谢你能看到这里,下一篇文章再见吧!