• express在nodejs中的基本使用


    express在nodejs中的基本使用

    基本使用

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

    有问题查看express官方文档:https://www.expressjs.com.cn/

    使用的express版本:npm i express@4.18.1

    创建一个最基本的express服务器

    和nodejs中的http模块创建服务器一样

    基本步骤: 引入模块 => 创建服务器 => 监听端口

    var express = require("express"); // npm i express 安装express模块,然后require导入express
    var server = express();  // 创建一个express http 服务器
    server.listen(8899, function () {
      console.log("服务启动:8899");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    监听请求

    get、post、put、delete都可以监听

    server.get("/getReq", function (req, res) {
      console.log("i got it");
      res.send("hello");
    });
    server.post("/postReq", function (req, res) {
      console.log("posted");
      res.send("world");
    });
    server.put("/putReq", function (req, res) {
      res.send("modify something");
    });
    server.delete("/delReq", function (req, res) {
      res.send("deleted something");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    托管静态文件

    express.static(root, [options])
    
    • 1

    第一个参数是托管那个文件夹下的文件

    第二个参数:

    var options = {
      dotfiles: 'ignore',
      etag: false,
      extensions: ['htm', 'html'],
      index: false,
      maxAge: '1d',
      redirect: false,
      setHeaders: function (res, path, stat) {
        res.set('x-timestamp', Date.now())
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    server.use(express.static("public"));  // public目录下所有的文件都作文静态文件托管
    http://localhost:8899/bgc.jpg  // 然后我们既可以直接可以访问到图片
    
    • 1
    • 2

    路由

    router.js文件,给他单独放在一个模块

    express.Router不能监听put和delete请求

    const express = require("express");  // Router是express中的一个函数,所以要先引入express
    const router = express.Router();     // 创建路由对象
    router.get("/getReq", (req, res) => {  // 将接口挂在到router上
      res.send("hello,gt");
    });
    router.post("/postReq", (req, res) => {
      res.send("hello,post");
    });
    module.exports = router;  // 暴露路由对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    server.js文件

    const router = require("./router.js");
    const server = express();  
    // server.use(router);
    server.use("/api", router);  // 可以在所有路由前添加一个公共的baseUrl
    server.listen(8888, () => {
      console.log("服务启动成功:8888");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以正则匹配,entry , try ,……

    router.get(/.*try$/, function (req, res) {
      res.send("reg");
    });
    
    • 1
    • 2
    • 3

    请求和响应的处理

    1》处理请求

    请求信息

    req.headers: 获取请求头信息

    处理 url 中的参数

    req.query  // 得到的是一个参数对象
    
    • 1

    处理 body 参数

    借助中间件body-parser,这是自带的中间件,不需要npm i

    const bodyParser = require("body-parser");
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    // req.body就可以拿到body中的参数了
    
    • 1
    • 2
    • 3
    • 4

    2》处理响应

    设置响应状态码:

    res.status(code) 
    res.status(200).send('hello')
    
    • 1
    • 2

    设置响应头:

    res.set(name,value) 
    res.set('Content-Type', 'text/plain')
    
    • 1
    • 2

    向客户端发送响应以及可选的状态码:res.send(body),res.send(stauts,body)

    设置浏览器处理文件的方式:res.attachment([filename]),res.download(path,[filename],[callback]) 这俩方法会将响应报头Content-Disposition设置为attachment(Content-Disposition:inline是展示,attachment为下载),浏览器会选择下载而不是展现内容。此外你还要把要下载的内容发到客户端;

    根据路径读取文件发到客户端:res.sendFile(path,[option],[callback])

    设置响应内容

    res.send([body])
    
    • 1

    body可以是 Buffer object, String, object, Boolean, 或者 Array

    设置content-type

    响应一个文件

    响应出去一个任意类型文件,也可以直接返回html文件做渲染

    res.sendFile(path [, options][, fn])
    
    • 1

    他会根据文件的后缀设置响应的Content-Type;options中可以设置响应的headers等

    中间件

    基本语法

    中间件实际上是函数,它有四个基本参数, err、req、res、next

    (err,req,res,next) => {}
    
    • 1

    app.use(中间件函数) 定义一个全局生效的中间件(app是express http实例)

    server.use((req,res,next)=>{
        next();
    });
    
    • 1
    • 2
    • 3

    分类

    1》全局中间件

    定义多个全局中间件,会按照定义顺序来执行

    多个中间件之间,共享同一份 reqres,因此可以在上游 的中间件中,统一为 reqres 对象添加自定义的属性和方法,供下游的中间件或路由进行使用

    server.use((req, res, next) => {  // 第一个中间件
      req.moreInfo = "additionInfo";
      next();
    });
    server.use((req, res, next) => {  // 第二个中间件
      console.log(req.moreInfo);
      next();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2》局部的中间件

    // 下面的中间件,只为当前接口 /test 这个接口服务
    app.get('/test', 中间件函数);
    // 下面的几个中间件,是处理 /api/hello 接口的,可以有多个中间件
    app.post('/api/hello', 中间件函数, 中间件函数, 中间件函数, 中间件函数 .....);
    
    
    路由中错误处理中间件(四个参数都要填,一般放到最后)
    router.use((err, req, res, next) => {
      // err 就是前面next过来的参数值
      res.send({ status: 400, message: err });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意事项

    1》一定要在路由之前注册中间件

    2》客户端发送过来的请求,可以连续调用多个中间件进行处理

    3》执行完中间件的业务代码之后,不要忘记调用 next() 函数

    4》为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码

    5》连续调用多个中间件时,多个中间件之间,共享 reqres 对象

    使用跨域中间件处理跨域问题

    // 导入 express 模块,并创建express http实例
    const express = require("express");
    const app = express();
    // 导入中间件cors,先得npm i,他不是内置模块
    const cors = require("cors");
    // 配置中间件,这里是全局的一个中间件
    app.use(cors());
    // 导入路由模块,并注册到 app 上
    const router = require("./router.js");
    app.use("/api", router);
    // 调用 app.listen 方法,指定端口号并启动 web 服务器
    app.listen(9000, () => {
      console.log("running……");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用实例:利用express下载一个pdf文件

    将self.pdf下载,并名命为test.pdf

    1》方法1:利用iframe标签下载

    router.get("/getStream", (req, res) => {
      res.set("Content-Type", "application/octet-stream");
      res.set("Content-Disposition", "attchment;filename=test.pdf");
      const rs = fs.createReadStream("./self.pdf");
      rs.on("data", function (data) {
        res.status(200).send(data);
      });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    创建一个iframe标签,设置iframe的src属性来请求文件流,Content-Disposition设置默认下载并取好文件名

        downPdf() {
          const IFRAME = document.createElement("iframe");
          IFRAME.style.display = "none";
          IFRAME.style.height = 0;
          // src 就是请求服务地址自行修改。
          IFRAME.src = `http://localhost:8080/api/getStream`;
          document.body.appendChild(IFRAME);
          setTimeout(() => {
            IFRAME.remove();
          }, 60 * 1000);
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法2:利用a标签下载

    router.get("/getStream", (req, res) => {
      res.set("Content-Type", "application/octet-stream");
      res.set("Content-Disposition", "inline");
      const rs = fs.createReadStream("./self.pdf");
      rs.on("data", function (data) {
        res.status(200).send(data);
      });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    一定要设置responseType:blob 或arraybuffer,不然下载打开是空白(这是个坑)

        dealClick() {
          axios
            .get("/api/getStream", {
              responseType: "blob",
            })
            .then((res) => {
              let blob = new Blob([res.data], {
                type: "application/pdf;charset-UTF-8",
              });
              const blobUrl = URL.createObjectURL(blob);
              const a = document.createElement("a");
              a.download = "gogo.pdf";
              a.style.display = "none";
              a.href = blobUrl;
              a.click();
              URL.revokeObjectURL(blobUrl);
            });
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    mysql操作
    基于node的tcp客户端和服务端的简单通信
    Nacos使用教程(三)——nacos注册中心(2)
    NLP教程(3) - 神经网络与反向传播
    前端开发各种loading效果【loading图的顺序对应代码顺序】
    56.5K star的gpt4free开源项目到底真的假的?
    微服务网关Gateway实践总结
    sentry安装过程故障排查
    #gStore-weekly | gStore最新版本0.9.1之BIND函数的使用
    一通骚操作,我把SQL执行效率提高了10000000倍!
  • 原文地址:https://blog.csdn.net/weixin_50576800/article/details/125462348