fastify框架获取上传的图片文件并保存到本地

版本说明

node版本:v20.15.1

{
  "dependencies": {
    "@fastify/cors": "^9.0.1",
    "@fastify/multipart": "^8.3.0",
    "@fastify/static": "^7.0.4",
    "fastify": "^4.28.1",
    "fastify-plugin": "^4.5.1"
  },
}

Fastify简介

Fastify是一个基于node的 web 开发框架,其设计灵感来自 Hapi 和 Express,致力于以最少的开销和强大的插件结构提供最佳的开发体验。它是这个领域里速度最快的 web 框架之一。
详情文档可查阅官网:https://fastify.dev

安装和注册插件

要获取到上传的图片文件,需要安装插件 @fastify/multipart,插件使用说明可以查看文档 https://github.com/fastify/fastify-multipart#readme 或者 https://www.npmjs.com/package/@fastify/multipart

npm i @fastify/multipart
//  yarn add @fastify/multipart
//  pnpm i @fastify/multipart

注册插件

import Fastify from "fastify";
import FastifyMultipart from "@fastify/multipart";
const app = Fastify({
  logger: false,
});
app.register(FastifyMultipart);

这里说明一下,我使用的node开发模式是ESM,不是CommonJs,因此不能直接使用__dirname,需要自行封装:

import path from "node:path";
import { fileURLToPath } from "node:url";
const _dirname = path.dirname(fileURLToPath(import.meta.url));

主入口文件app.js完整代码如下:

import path from "node:path";
import { fileURLToPath } from "node:url";
import Fastify from "fastify";
import fastifyStatic from "@fastify/static";
import FastifyMultipart from "@fastify/multipart";
import cors from "@fastify/cors";

import { port } from "./config/index.js";
import router from "./router/index.js";
const app = Fastify({
  logger: false,
});

let _dirname = path.dirname(fileURLToPath(import.meta.url));

// 注册静态资源
app.register(fastifyStatic, {
  root: path.join(_dirname, "./public"),
  prefix: "/public/",
});
// 注册跨域
app.register(cors);
// 注册文件上传
app.register(FastifyMultipart);
// 注册路由
app.register(router);
app.listen({ port, host: "127.0.0.1" }, function (err, address) {
  if (err) {
    app.log.error(err);
    process.exit(1);
  }
  console.log(`服务器启动成功:http://127.0.0.1:${port}`);
});

为了使上传的图片文件名保存不重复,避免覆盖,这里对文件名采用hash命名,单独创建hash.js文件,代码如下:

const { createHmac } = await import("node:crypto");

export function Hash() {
  //考虑到文件名的唯一性,createHmac的第二个参数这里使用的是时间戳,然后转为字符串
  //这个时间戳不是必须的,也可以在自定义
  let hash = createHmac("sha256", new Date().getTime().toString())
    .update("imageFiles")
    .digest("hex");
  return hash.slice(0, 20);//保留20位字符
}

图片上传接口

创建router文件夹,新建index.js,代码如下:

import fs from "node:fs";
import util from "node:util";
import path from "node:path";
import url from "node:url";
import { pipeline } from "node:stream";
import { Hash } from "../utils/hash.js";

const _dirname = path.dirname(url.fileURLToPath(import.meta.url));

async function routes(app, options) {
  //图片上传接口
  app.post(`/api/uploadImg`, async (request, reply) => {
    const data = await request.file();
    //data是获取到的图片文件资源和相关信息
    console.log(data);
    //拿到后缀名
    let extname = path.extname(data.filename); //结果是  .jpg/.png等
    //图片名称
    let imgName = Hash() + extname;
    //图片保存路径
    let imgPath = path.join(_dirname, `../public/img/${imgName}`);

    const pump = util.promisify(pipeline);

    //将获取到的图片文件保存到本地
    await pump(data.file, fs.createWriteStream(imgPath));
    //获取图片描述(即除了后缀名外的原图片名)
    let imgDesc = data.filename.slice(0, data.filename.lastIndexOf("."));
    reply.send({
      errno: 0,
      data: {
        url: `http://127.0.0.1:4003/public/img/${imgName}`,
        alt: imgDesc || "图片描述",
        href: "", //图片链接
      },
    });
  });
  //其他接口
}
export default routes;

目录结构示例
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值