Next.js 实战 (六):如何实现文件本地上传

简介: 这篇文章介绍了在Next.js中如何实现文件上传到本地的方法。文章首先提到Next.js官方文档中没有提供文件上传的实例代码,因此开发者需要自行实现,通常有两种思路:使用Node.js原生上传或使用第三方插件如multer。接着,文章选择了使用Node.js原生上传的方式来讲解实现过程,包括如何通过哈希值命名文件、上传到指定目录以及如何分类文件夹。然后,文章展示了具体的实现步骤,包括编写代码来处理文件上传,并给出了代码示例。最后,文章通过一个效果演示说明了如何通过postman模拟上传文件,并展示了上传后的文件夹结构。

前言

在我们的日常工作中,上传文件、导入 Excel 表格数据这些是不可避免的,那在 Next.js 该如何实现上传文件到本地呢?

Next.js 的官方文档并没有相应的实例代码,需要开发者自行实现,一般来说有两种思路:

  1. 使用 Node.js 原生上传
  2. 使用第三方插件,如:multer

本文将以第一种方式实现:使用 Node.js 原生上传

业务设计

  1. 上传的文件使用哈希值命名,也可自己拼接上原文件名
  2. 文件上传到指定目录,这里我们指令上传的目录为:public/uploads,因为上传到这个目录,我们就能直接通过 /uploads/xxx.jpg 访问文件
  3. 上传目录的文件夹将以 YYYYMM 年月的格式分类,可以自定义

具体步骤

新建 app/api/upload/route.ts 文件,写入代码:

import crypto from 'crypto';
import dayjs from 'dayjs';
import {
    existsSync } from 'fs';
import fs from 'fs/promises';
import {
    NextRequest, NextResponse } from 'next/server';
import path from 'path';

import {
    RESPONSE_MSG } from '@/enums';
import {
    responseMessage } from '@/lib/utils';

export async function POST(req: NextRequest) {
   
  try {
   
    // 获取二进制文件数据
    const formData = await req.formData();

    const f = formData.get('file');

    if (!f) {
   
      return NextResponse.json({
   }, {
    status: 400 });
    }

    const file = f as File;

    const yearMonth = dayjs().format('YYYYMM');

    // 获取当前年月并创建对应的文件夹
    const uploadDir = path.join(process.cwd(), 'public/uploads', yearMonth);

    // 如果文件夹不存在,则创建
    if (!existsSync(uploadDir)) {
   
      await fs.mkdir(uploadDir, {
    recursive: true });
    }

    // 将文件保存到服务器的文件系统中
    const fileArrayBuffer = await file.arrayBuffer();

    // 生成哈希值作为文件名
    const hash = crypto.randomBytes(16).toString('hex');

    // 生成文件名
    const fileName = `${
     hash}.${
     file.name.split('.')[1]}`;

    // 将文件上传到 uploads 文件夹
    await fs.writeFile(path.join(uploadDir, fileName), Buffer.from(fileArrayBuffer));

    return NextResponse.json(
      responseMessage({
   
        fileName,
        size: file.size,
        url: `/uploads/${
     yearMonth}/${
     fileName}`,
      }),
    );
  } catch (error) {
   
    return NextResponse.json(responseMessage(error, RESPONSE_MSG.ERROR, -1));
  }
}

代码都有注释,我感觉还是比较好容易理解的

前端使用

前端可以通过 FormData 格式提交数据:

// 上传头像
  const { loading: uploadLoading, run: runUploadAvatar } = useRequest(uploadFile, {
    manual: true,
    onSuccess: ({ code, data }) => {
      if (isSuccess(code)) {
        setAvatar(data.url);
      }
    },
  });

  // 图片上传回调
  const handleFileChange: ChangeEventHandler<HTMLInputElement> = (event) => {
    const file = event.target.files?.[0];
    if (file) {
      // 创建一个 FormData 对象
      const formData = new FormData();
      formData.append('file', file);
      runUploadAvatar(formData);
    }
  };

<Input
  name="avatar"
  type="file"
  accept="image/*"
  className="w-20"
  onChange={handleFileChange}
  size="sm"
  />

效果演示

我们通过 postman 模拟上传:
enximxzjjzo4e98wjkkl6bntl56d60um.gif

上传后的文件夹结构:
lanwl65hpnl7z6tiofwcqdsmonmx1p2w.png

总结

这里只实现了单个文件上传,批量上传或者文件数组的需要自行实现,现在很少有上传文件到服务器本地的,业务量大的话会对服务器造成压力,一般这种适合个人站点、博客使用,这里我们当做学习就行。

Githubnext-admin

相关文章
|
9月前
|
人工智能 自然语言处理 JavaScript
通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
458 4
 通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
|
5月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
7月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
197 1
|
6月前
|
编解码 JavaScript 前端开发
如何在网页播放英文的m3u8文件(基于Javascript搭建的在线网页工具)
什么是m3u8?又该如何在网页中高效、便捷地播放英文的m3u8文件呢?今天这篇文章就带你一起了解,并推荐一种基于Javascript搭建的在线网页工具,让你轻松解决播放问题。
1313 0
|
11月前
|
监控 JavaScript 前端开发
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
MutationObserver 是一个非常强大的 API,提供了一种高效、灵活的方式来监听和响应 DOM 变化。它解决了传统 DOM 事件监听器的诸多局限性,通过异步、批量的方式处理 DOM 变化,大大提高了性能和效率。在实际开发中,合理使用 MutationObserver 可以帮助我们更好地控制 DOM 操作,提高代码的健壮性和可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
|
监控 安全 中间件
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
这篇文章介绍了什么是Next.js中的中间件以及其应用场景。中间件可以用于处理每个传入请求,比如实现日志记录、身份验证、重定向、CORS配置等功能。文章还提供了一个身份验证中间件的示例代码,以及如何使用限流中间件来限制同一IP地址的请求次数。中间件相当于一个构建模块,能够简化HTTP请求的预处理和后处理,提高代码的可维护性,有助于创建快速、安全和用户友好的Web体验。
341 0
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
467 1
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
中间件 API
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
这篇文章介绍了作者在使用Nextjs15进行项目开发时遇到的部署问题。在部署过程中,作者遇到了打包构建时的一系列报错,报错内容涉及动态代码评估在Edge运行时不被允许等问题。经过一天的尝试和调整,作者最终删除了lodash-es库,并将radash的部分源码复制到本地,解决了打包报错的问题。文章最后提供了项目的线上预览地址,并欢迎读者留言讨论更好的解决方案。
357 0
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
|
设计模式 数据安全/隐私保护
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
459 0
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
|
前端开发 API 开发者
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
394 0
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画

热门文章

最新文章