node.js学习笔记(express和中间件)

express 模块

express 简介

express 是基于Node.js的 http 创建出的平台,开放、极简的 web 开发框架。本质上是npm 的第三方包。中文官网: http://www.expressjs.com.cn/

作用:

  1. 专门提供 web 网页资源的服务器(web 网站服务器)
  2. 专门对外提供 api 接口的服务器(API 接口服务器)
express 的基本使用

安装:

npm i express@4.17.1

创建基本的 web 服务器

//导入
const express = require("express");
//创建服务器
const app = express();
//调用app.listen
app.listen(8080, () => {
  console.log("server running at http://127.0.0.1:8080");
});
监听 GET和POST 请求

通过 app.get()方法,可以监听客户端的 get 请求。

语法格式:

app.get("请求URL", function (req, res) {
  /*处理函数*/
});

参数解读:

  • '请求URL' : 客户端请求的 url 地址
  • function (req, res) { /*处理函数*/ }: 请求的处理函数
    • req : 请求对象(包含了与请求相关的属性与方法)
    • res:响应对象(包含了与响应有关的属性和方法)

通过 app.post()方法,可以监听客户端的 get 请求。

语法格式:

app.post("请求URL", function (req, res) {
  /*处理函数*/
});

参数解读:

  • '请求URL' : 客户端请求的 url 地址

  • function (req, res) { /*处理函数*/ }: 请求的处理函数

    • req : 请求对象(包含了与请求相关的属性与方法)
    • res:响应对象(包含了与响应有关的属性和方法)
把内容响应给客户端

使用res.send()方法。

app.get("/user", (req, res) => {
  //向客户端发送JSON对象
  res.send({ name: "tom", age: 30, gender: "男" });
});
app.post("/user", (req, res) => {
  console.log("请求成功!");
});
获取 url 中携带的查询参数

通过res.query()对象,可以访问到客户端查询字符串的形式,发送到服务器的参数

app.get("/", (req, res) => {
  //req.query 默认是空对象
  //客户端发送 ?name=zs&age=20
  // 可以通过req.query查询到
  // req.query.name    req.query.age
  console.log(req.query);
});

练习:

const express = require("express");

const app = express();

app.get("/user", (req, res) => {
  console.log(req.query);
  res.send({ name: "tom", age: 40, gender: "男" });
});

app.post("/user", (req, res) => {
  console.log("请求成功");
});

app.listen(8080, () => {
  console.log("server running at http://127.0.0.1:8080");
});

结果:
在这里插入图片描述

通过 req.params对象,可以访问到 url 中通过 : 匹配到的动态参数(例如:http://127.0.0.1/user/:id

app.get("/user/:id", (req, res) => {
  console.log(req.params);
});

结果:
在这里插入图片描述

托管静态资源
  1. express.static()

    通过这个函数,可以很方便地创建一个静态资源服务器。例如,通过如下代码将 public 目录下的图片、css 文件、js 文件对外开放访问。

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

注意:
express 在静态目录查找文件,并对外提供资源的访问路径。但是存放静态资源的目录名不会出现在URL中

  • http://localhost:3000/images/bg.png
  • http://localhost:3000/css/style.css
  • http://localhost:3000/js/login.js
挂载路径前缀
app.use("public", express.static("public"));

访问路径变成如下:

  • http://localhost:3000/public/images/bg.png
  • http://localhost:3000/public/css/style.css
  • http://localhost:3000/public/js/login.js
nodemon

当代码修改时,nodemon可以帮我们重启项目,方便开发和调试。

安装 nodemon

//安装nodemon全局工具
npm i nodemon -g

使用 nodemon

nodemon app.js
express 路由
初识路由

路由指的是客户端的请求服务器处理函数之间的映射关系
express 的路由由请求的类型请求的URL地址处理函数

格式:

app.METHOD(PATH, HANDLER);

例子:

//匹配GET请求 且URL为 /
app.get("/", function (req, res) {
  res.send("hello world");
});

//匹配POST请求 且URL 为 /
app.post("/", function (req, res) {
  res.send("Get a post request");
});

module.exports = router;
路由的匹配过程

当有一个请求到达服务器之后,需要先进行路由的匹配,只有匹配成功之后,才会调用对应的处理函数。

模块化路由

为了方便对路由进行模块化的管理,express 不建议将路由直接挂载到 app 上,而是推荐将路由抽离为单独的模块。

步骤:

  1. 创建路由模块对应的.js 文件
  2. 调用express.Router()函数创建路由对象
  3. 向路由对象上挂载具体的路由
  4. 使用module.exports向外共享路由对象
  5. 使用app.use()注册路由模块
var express = require("express"); // 导入express
var router = express.Router(); // 创建路由对象
router.get("/user/list", (req, res) => {
  res.send("Get user list");
});

router.post("/user/add", (req, res) => {
  res.send("add new user");
});

注册路由

app.use(router);

为路由添加前缀

和为静态资源统一挂载访问前缀一样

const userRouter = require("./router/user.js");

//使用app.use()注册模块 并添加前缀
app.use("api", userRouter);
中间件

当一个请求到达 express 服务器时,可以调用多个中间件,从而对这次请求进行预处理

格式:

本质上是 function 函数

在这里插入图片描述

注意:

中间件函数的形参列表中,必须包含next参数。而路由处理函数只包含 req,res.

next 函数的作用

next 函数是实现多个中间件连续调用的关键,它表示把流转关系移交给了下一个中间件或路由。

定义中间件函数
const mw = function (req, res, next) {
  console.log("这是一个中间件函数");
  //当处理完此中间件的业务时,必须调用next()函数
  next();
};
全局生效的中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。通过调用app.use(中间件函数),计科定义一个 全局生效中间件

代码:

const mw = function (req, res, next) {
  console.log("这是一个中间件函数");
  next();
};

//全局生效
app.use(mw);

简化形式:

app.use(function (req, res, next) {
  console.log("");
  next();
});

中间件的作用

多个中间件之间,共享同一份req和res,基于这样的特性,我们可以在上游的中间件中,同意为 req 和 res 添加自定义的属性或方法,供下游的中间件使用。

定义多个全局中间件

可以使用app.use()连续定义多个全局中间件,服务器会安装定义的前后顺序依次调用

app.use(function (req, res, next) {
  console.log("1");
  next();
});
app.use(function (req, res, next) {
  console.log("2");
  next();
});
app.use(function (req, res, next) {
  console.log("3");
  next();
});
app.use(function (req, res, next) {
  console.log("4");
  next();
});
局部生效的中间件

不使用app.use()定义的中间件,叫做局部生效的中间件,代码:

// 定义中间件
const mw1 = function (req, res, next) {
  console.log("中间件函数");
  next();
};

//mw1中间件只在当前路由中生效’
app.get("/", mw1, function (req, res) {
  res.send("Home page");
});

//mw1中间件不会影响这个路由↓↓
app.get("/user", function (req, res) {
  console.log("user page");
});
定义多个局部中间件

可以在路由中,通过如下两种等价的方式:

app.get("/", mw1, mw2, function (req, res) {
  res.send("Home page");
});

app.get("/", [mw1.mw2], function (req, res) {
  res.send("Home page");
});

注意事项:

  1. 一定要在路由之前注册中间件
  2. 客户端发来的请求,可以连续调用多个中间件进行处理
  3. 执行完中间件的业务代码之后,要调用next()函数
  4. 在调用next()之后不要再写额外的代码
  5. 连续调用多个中间件时,多个中间件之间,共享 req 和 res
错误级别的中间件

专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题

格式:

function(err,req,res,next){}

注意
必须注册在所有路由之后

express 内置中间件
  1. express.static() 快速托管静态资源(无兼容性)
  2. express.json() 解析 JSON 格式的请求体数据 (4.16.0+)
  3. express.urlencoded() 解析 url-encoded 格式的请求体数据(4.16.0+)
//配置解析json格式
app.use(express.json());
//配置urlencoded
app.use(express.urlencoded({ extended: false }));
第三方中间件

非官方内置,按需下载
例如:body-parser中间件解析请求体

  1. 安装body-parser中间件
  2. 使用 require() 导入中间件
  3. 调用 app.use()注册并使用中间件
自定义中间件

步骤:

  1. 定义中间件
  2. 监听 req 的 data 事件
  3. 监听 req 的 end 事件
  4. 使用querystring模块解析请求体数据
  5. 将解析出来的数据对象挂载为 req.body
  6. 将自定义中间件封装为模块

在这里插入图片描述

编写 GET 和 POST 请求

apiRouter.js

const express = require("express");
const router = express.Router();

router.get("/get", (req, res) => {
  // 获取请求字符串
  const query = req.query;
  res.send({
    status: 0, // 状态  0:成功; 1: 失败
    msg: "Get请求成功!", //状态描述
    data: query, // 响应给客户端的数据
  });
});

router.post("/post", (req, res) => {
  const body = req.body;
  console.log(body);
  res.send({
    status: 0,
    msg: "Post请求成功",
    data: body,
  });
});

module.exports = router;

GET 和 POST 请求

const express = require("express");
const app = express();
const port = 8080;

//解析表单数据  一定要在请求之前
app.use(express.urlencoded({ extended: false }));
const router = require("./apiRouter");
app.use("/api", router);

app.listen(port, () => {
  console.log(`server running port at ${port}`);
});
解决跨域问题

在这里插入图片描述

当客户端和服务端协议不同时,使用 ajax 并不能发送成功。

使用 cors 中间件解决跨域问题

cors 由一系列 http 响应头组成,决定了浏览器是否阻止前端 js 代码跨域获取资源
浏览器的安全同源策略默认会阻止网页“跨域”获取资源,当配置 cors 响应头之后就可以解除限制。(有兼容性问题)

  1. 安装 npm i cors
  2. 导入 require('cors')
  3. 在路由器之前调用 app.use(cors())
const cors = require("cors");
app.use(cors());
cors 相关的响应头
  1. Access-control-Allow-Origin
// 例:允许所有
res.setHeader("Access-control-Allow-Origin", "*");
  1. Access-control-Allow-Headers
  • 默认情况下,cors 仅支持客户端向服务器发送九个请求头,如果发送了额外的请求头信息,则需要在服务器端,通过Access-control-Allow-Headers声明,否则请求就会失败
  1. Access-control-Allow-Methods
  • 默认情况下,cors 仅支持客户端发送 get、post、head 请求
    ,如果希望视同 put、delete 请求资源,则需要在服务器端,通过Access-control-Allow-Methods来致命实际请求所允许使用的 http 方法
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

章鱼哥vlog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值