express的基本使用

本文介绍了Node.js开发中的一些常用工具和技术,包括Express框架的使用,CORS跨域处理,formidable模块处理文件上传,multer中间件处理多部分表单,以及SequelizeORM进行数据库操作。还涉及时间处理、MD5加密、随机数生成和cookie验证等方面,详细阐述了每个技术的关键点和示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 安装

  • npm i express

  • 安装express生成器,类似与脚手架

    npm install -g express-generator

  • 默认对外暴露一个express 指令

  • express -h查看帮助

2. cors

  1. yarn add cors

  2. 引入 var cors = require("cors");

  3. 注册 app.use(cors()); //对象

3.注意

  1. __dirname:表示当前文件的父级目录

4.formidable的使用

  • 这个包可以处理一些表单数据,包含文件的操作

  1. 安装 yarn add formidable

  2. 引入 const formidable = require("formidable");

  3. 创建实例

  4. const form = formidable(options);

    options:配置项是一个对象{

    • 文件上传路径 uploadDir

    • keepExtensions 显示拓展名=>布尔值

    • allowEmptyFiles 允许为空吗=>布尔值

    • filename 自定义文件名 =>函数(name, ext, part, form)分别对应原本上传的文件名,文件后缀,文件信息,表单信息

    }

  5. form.parse解析表单信息

    formidable 模块中包含的事件 在使用parse方法对表单进行解析时,解析对象经历了一系列过程,我们可以监听这些过程从而完成某些操作,这些过程我们可以理解为事件。

    progress:当有数据块被处理之后会触发该事件。具体语法:form.on('progress', (bytesReceived, bytesExpected) => {}); field:每当一个字段 / 值对已经收到时会触发该事件。具体语法:form.on('field', (name, value) => {}); fileBegin:在post流中检测到任意一个新的文件便会触发该事件。具体语法:form.on('fileBegin', (name, file) => {}); file:每当有一对字段/文件已经接收到,便会触发该事件。具体语法:form.on('file', (name, file) => {}); error:当上传流中出现错误便会触发该事件,当出现错误时,若想要继续触发request的data事件,则必须手动调用request.resume()方法。具体语法:form.on('error', (err) => {}); aborted:当用户中止请求时会触发该事件。具体语法:form.on('aborted', () => {}); end:当所有的请求已经接收到,并且所有的文件都已上传到服务器中,该事件会触发。具体语法:form.on('end', () => {});

5.时间处理

  1. 安装 npm i moment

  2. .moment()即可获取现在的时间

  3. moment.format('l')获取现在时间的时间戳

6.multer的使用

Multer 会添加一个 body 对象 以及 filefiles 对象 到 express 的 request 对象中。 body 对象包含表单的文本域信息,filefiles 对象包含对象表单上传的文件信息。

  1. 安装 yarn add multer

  2. 引入并且配置

    const **multer** = **require**("multer");
    ​
    const storage = multer.diskStorage({
    ​
     **destination**: function (req, file, **cb**) {
    ​
      **cb**(null, "public/images");
    ​
     },
    ​
     **filename**: function (req, file, **cb**) {
    ​
      **cb**(null, Date.**now**() + "-" + file.originalname);
    ​
     },
    ​
    });
    ​
    ​
    ​
    const upload = **multer**({ storage: storage });

destination:要存储的路径

filename:要存储的名字

const express = require('express')
const multer  = require('multer')
const upload = multer({ dest: 'uploads/' })
​
const app = express()
​
app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file 是 `avatar` 文件的信息
  // req.body 将具有文本域数据,如果存在的话
})
​
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
  // req.files 是 `photos` 文件数组的信息
  // req.body 将具有文本域数据,如果存在的话
})
​
const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
  // req.files 是一个对象 (String -> Array) 键是文件名,值是文件数组
  //
  // 例如:
  //  req.files['avatar'][0] -> File
  //  req.files['gallery'] -> Array
  //
  // req.body 将具有文本域数据,如果存在的话
})

7.ORM

  1. 安装依赖 yarn add sequelize

    安装相关数据库连接

    npm i pg pg-hstore # PostgreSQL npm i mysql2 # MySQL npm i mariadb # MariaDB npm i sqlite3 # SQLite npm i tedious # Microsoft SQL Server npm i ibm_db # DB2

    yarn add pg pg-hstore # PostgreSQL yarn add mysql2 # MySQL yarn add mariadb # MariaDB yarn add sqlite3 # SQLite yarn add tedious # Microsoft SQL Server yarn add ibm_db # DB2

  2. 链接数据库

    • 引入两个依赖

      const mysql2 = require("mysql2");
      const Sequelize = require("sequelize");

    • 创建实例

      const sequelize = new Sequelize("todoserver", "root", "xxxxxx", {
        host: "localhost",
        dialect: "mysql",
        pool: {
          max: 5,
          min: 0,
          acquire: 30000,
          idle: 10000,
        },
      });

      todoserver:数据库名字

      root:用户名

      xxxxxx:密码

      dialect:要连接什么数据库

      pool:创建连接池

  3. 判断是否链接成功

    sequelize
      .authenticate()
      .then(() => {
        console.log("Connection has been established successfully.");
      })
      .catch((err) => {
        console.error("Unable to connect to the database:", err);
      });
    ​

    sequelize.authenticate()方法返回一个promis对象他的状态就是我们链接数据库成功与否的状态

  4. 模型

    1. 定义模型

      方法一

      继承 Model

      class Todo extends Model {}
      class User extends Model {}
      ​
      User.init(
        {
          name: {
            type: DataTypes.STRING,
          },
          pic: {
            type: DataTypes.TEXT,
          },
        },
        {
          tableName: "Users",
          sequelize,
        }
      );
      ​
      ​
      Todo.init(
        {
          label: {
            type: DataTypes.STRING,
            allowNull: false,
          },
          disabled: {
            type: DataTypes.BOOLEAN,
            defaultValue: false,
          },
          key: {
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
          },
        },
        {
          tableName: "todos",
          sequelize,
        }
      );

      方法二

      使用 define()

      const { Sequelize, DataTypes } = require('sequelize');
      const sequelize = new Sequelize('sqlite::memory:');
      ​
      const User = sequelize.define('User', {
        // 在这里定义模型属性
        firstName: {
          type: DataTypes.STRING,
          allowNull: false
        },
        lastName: {
          type: DataTypes.STRING
          // allowNull 默认为 true
        }
      }, {
        // 这是其他模型参数
      });
      ​
      // `sequelize.define` 会返回模型
      console.log(User === sequelize.models.User); // true
    2. 删除表

      await User.drop();
      console.log("用户表已删除!");

    3. 同步模型

      单独同步

      await User.sync({ force: true });
      console.log("用户模型表刚刚(重新)创建!");

      一次性同步

      await sequelize.sync({ force: true });
      console.log("所有模型均已成功同步.");

    4. 使用模型进行curd

      • 插入数据

      modle表示要操作的表

      modle.create({
          字段:值
      })
      //例子:
       async addTodo(req, res) {
          const { label } = req.body;
          await Todo.create({
            label: label,
          });
          res.status(200).send({
            code: 200,
            data: req.body,
          });
        },
      ​
      • 删除数据

        // 删除所有名为 "Jane" 的人 
        await User.destroy({
          where: {
            firstName: "Jane"
          }
        });

        删除所有

        // 截断表格
        await User.destroy({
          truncate: true
        });

      • 更新数据

        model.update({要更新的字段},{where:{}})
        ​
        // 将所有没有姓氏的人更改为 "Doe"
        await User.update({ lastName: "Doe" }, {
          where: {
            lastName: null
          }
        });
  5. 查询

    查询全部findAll()

    where条件查询

    const { Op } = require("sequelize");
    Post.destroy({
      where: {
        authorId: {
          [Op.or]: [12, 13]
        }
      }
    });
    // DELETE FROM post WHERE authorId = 12 OR authorId = 13;

通过主键查找

findByPk()

const project = await Project.findByPk(123);
if (project === null) {
  console.log('Not found!');
} else {
  console.log(project instanceof Project); // true
  // 它的主键是 123
}

返回第一条查找到的数据

findOne()

const project = await Project.findOne({ where: { title: 'My Title' } });
if (project === null) {
  console.log('Not found!');
} else {
  console.log(project instanceof Project); // true
  console.log(project.title); // 'My Title'
}

8.关联

  • HasOne 关联类型

  • BelongsTo 关联类型 在原目标创建外键

  • HasMany 关联类型

  • BelongsToMany 关联类型

const A = sequelize.define('A', /* ... */);
const B = sequelize.define('B', /* ... */);

A.hasOne(B); // A 有一个 
A.belongsTo(B); // A 属于 B
A.hasMany(B); // A 有多个 B
A.belongsToMany(B, { through: 'C' }); // A 属于多个 B , 通过联结表 C
  1. 一对一关系

    通过

    A.hasOne(B); // A 有一个 B 在B表创建外键
    B.belongsTo(A); // A 属于 B 在B表创建外键

    自动将主键设置为外键

    也可以自定义外键

    // 方法 1
    Foo.hasOne(Bar, {
      foreignKey: 'myFooId'
    });
    Bar.belongsTo(Foo);
    
    // 方法 2
    Foo.hasOne(Bar, {
      foreignKey: {
        name: 'myFooId'
      }
    });
    Bar.belongsTo(Foo);
    
    // 方法 3
    Foo.hasOne(Bar);
    Bar.belongsTo(Foo, {
      foreignKey: 'myFooId'
    });
    
    // 方法 4
    Foo.hasOne(Bar);
    Bar.belongsTo(Foo, {
      foreignKey: {
        name: 'myFooId'
      }
    });
  2. 一对多

    通过

    Team.hasMany(Player);
    Player.belongsTo(Team);

    也可以自定义外键字方法跟一对一关联一样

  3. 多对多关系

    通过第三方表实现

    const Movie = sequelize.define('Movie', { name: DataTypes.STRING });
    const Actor = sequelize.define('Actor', { name: DataTypes.STRING });
    Movie.belongsToMany(Actor, { through: 'ActorMovies' });
    Actor.belongsToMany(Movie, { through: 'ActorMovies' });

ActorMovies:自动创建一个关联表

也可以自己定义一个关联表

const Movie = sequelize.define('Movie', { name: DataTypes.STRING });
const Actor = sequelize.define('Actor', { name: DataTypes.STRING });
const ActorMovies = sequelize.define('ActorMovies', {
  MovieId: {
    type: DataTypes.INTEGER,
    references: {
      model: Movie, // 'Movies' 也可以使用
      key: 'id'
    }
  },
  ActorId: {
    type: DataTypes.INTEGER,
    references: {
      model: Actor, // 'Actors' 也可以使用
      key: 'id'
    }
  }
});
Movie.belongsToMany(Actor, { through: ActorMovies });
Actor.belongsToMany(Movie, { through: ActorMovies });

获取关系

  1. 延迟获取(需要时再去取,类似懒加载)

  2. 预先加载

    const awesomeCaptain = await Captain.findOne({
      where: {
        name: "Jack Sparrow"
      },
      include: Ship
    });
    // 现在 ship 跟着一起来了
    console.log('Name:', awesomeCaptain.name);
    console.log('Skill Level:', awesomeCaptain.skillLevel);
    console.log('Ship Name:', awesomeCaptain.ship.name);
    console.log('Amount of Sails:', awesomeCaptain.ship.amountOfSails);

在查询时添加include配置项即可

9.Sequelize脚手架

  1. 安装 yarn add sequelize-cli --dev

  2. 初始化 yarn sequelize-cli init

  3. 配置数据库 config/config.json

    {
      "development": {
        "username": "root",
        "password": null,
        "database": "database_development",
        "host": "127.0.0.1",
        "dialect": "mysql"
      },
      "test": {
        "username": "root",
        "password": null,
        "database": "database_production",
        "host": "127.0.0.1",
        "dialect": "mysql"
      },
      "production": {
        "username": "root",
        "password": null,
        "database": "database_test",
        "host": "127.0.0.1",
        "dialect": "mysql"
      }
    }
  4. 建库 yarn sequelize-cli db:create , 删库 yarn sequelize-cli db:drop

  5. 创建模型 yarn sequelize-cli model:generate --name 表名 --attributes 字段名:类型,字段名:类型

  6. 迁移 yarn sequelize-cli db:migrate

  1. 创建迁移文件 yarn sequelize-cli migration:create --name 文件名

  2. 恢复最近迁移 yarn sequelize-cli db:migrate:undo

  3. 撤销所有迁移,恢复最开始的状态 yarn sequelize-cli db:migrate:undo:all

  4. 恢复指定迁移 yarn sequelize-cli db:migrate:undo:all --to 迁移文件名

  1. 创建种子文件 yarn sequelize-cli seed:generate --name 种子名字

  2. 撤销最近种子 yarn sequelize-cli db:seed:undo

  3. 撤销全部种子 yarn sequelize-cli db:seed:undo:all

  4. 撤销指定种子 yarn sequelize-cli db:seed:undo --seed 种子名

10.md5加密

  1. 引入内置模块const crypto = require('crypto');

const originalText = 'hello world';
// 使用 md5 算法创建哈希对象
const hash = crypto.createHash('md5');
// 更新哈希对象内容
hash.update(originalText);
// 生成加密后的内容
const encryptedText = hash.digest('hex');

11.随机数的使用

for (let i = 0; i < saltArr.length - 2; i++) {
      let randomIdx = Math.floor(Math.random() * saltArr.length);
      saltStr += saltArr[randomIdx];
    }

12.验证

  1. cookie

    • 设置cookie res.cookie("name", "zhangsan", { maxAge: 60 * 1000 });

      下次请求会自动携带这个cookie到服务器

    • 删除cookie res.clearCookie('cookie的名字')

    • 获取cookie 使用cookie-parser

    • var cookieParser = require("cookie-parser");
      app.use(cookieParser());
    • req.cookies.name

  2. session

    用户登录 => 验证通过 => 保存session =>返回cookie

    使用sequelize-cli设置sessionStore

    1. 安装 express-session

    2. 安装 npm i connect-session-sequelize

    3. 引入

      const session = require("express-session");
      const { sequelize } = require("./models/index.js");
      const SequelizeStore = require("connect-session-sequelize")(session.Store);
    4. 设置仓库 const myStore = new SequelizeStore(options);

      options配置项

      • db成功连接的 Sequelize 实例

      • table (可选)已导入到Sequelize实例的表/模型,如果要在数据库中使用特定表,则可以使用它

      • modelKey可选)Sequelize的models-object中键的字符串,但它也是它引用的类的名称(通常用Camelcase编写),这就是为什么如果未定义,则默认为“会话”。table

      • tableName (可选)用于命名生成的表(如果未定义的字符串。 默认值为 的值。table``modelKey

      • extendDefaultFields (可选)一种将自定义数据添加到表列的方法。如果使用自定义模型定义,则很有用

      • disableTouch (可选)如果为 true,则存储不会在收到 touch() 调用时更新数据库。这对于限制数据库写入和引入更多会话更新的手动控制非常有用。

    5. 设置session

      app.use(
        session({
          name: "sid",
          resave: true,
          saveUninitialized: false,
          secret: "o^-^o",
          store: myStore,
          cookie: {
            httpOnly: true,
            maxAge: 1000 * 60 * 60 * 24 * 7,
          },
        })
      );
    6. 同步仓库模型(connect-session-sequelize帮我们创建的) myStore.sync();

    7. 全部代码

      const myStore = new SequelizeStore({ db: sequelize });
      app.use(
        session({
          name: "sid",
          resave: true,
          saveUninitialized: false,
          secret: "o^-^o",
          store: myStore,
          cookie: {
            httpOnly: true,
            maxAge: 1000 * 60 * 60 * 24 * 7,
          },
        })
      );
      myStore.sync();
    8. 设置(更操作普通对象一样的操作)

    9. 读取(更操作普通对象一样的操作)

    10. 销毁 req.session.destroy('session的名字')

    11. 获取sessionID ==> req.sessionID

  3. otken验证

  4. 安装 yarn add jsonwebtoken

  5. 引入 。。。

  6. 设置token jwt.sign(保存在token的对象,盐,options)

  7. 校验token jwt.varify(token,盐,成功的回调

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值