如何配置Nuxt 3实现用户上传文件的动态存储与访问
Nuxt3 动态上传文件夹的配置与实现方案
问题根源
Nuxt3 的 public 目录属于静态资源目录,构建时会被打包到产物中,运行时新增的文件不在构建范围内,因此无法直接访问。要实现动态上传后立即访问,不能依赖静态目录,需要通过服务器路由和动态资源映射来处理。
正确实现步骤
1. 创建独立的上传目录
在项目根目录下创建 uploads 文件夹(不要放在 public 内),确保该目录具备读写权限(Linux/macOS 可执行 chmod -R 755 uploads)。
2. 配置 Nitro 映射动态资源
在 nuxt.config.ts 中通过 Nitro 的 publicAssets 配置,将本地 uploads 目录映射为可通过 URL 访问的动态资源:
export default defineNuxtConfig({ nitro: { publicAssets: [ { baseURL: '/uploads', // 访问前缀 dir: './uploads', // 本地目录路径 maxAge: 0 // 禁用缓存,保证新上传文件即时可见 } ] } })
3. 编写文件上传接口
在 server/api/upload.post.ts 中实现后端上传逻辑,处理表单数据并写入 uploads 目录:
import { writeFile } from 'fs/promises' import { join } from 'path' export default defineEventHandler(async (event) => { const formData = await readMultipartFormData(event) if (!formData) { return createError({ statusCode: 400, statusMessage: '未上传文件' }) } const fileItem = formData.find(item => item.name === 'file') if (!fileItem) { return createError({ statusCode: 400, statusMessage: '表单中未找到文件' }) } // 生成唯一文件名避免覆盖 const fileName = `${Date.now()}-${fileItem.filename}` const filePath = join(process.cwd(), 'uploads', fileName) await writeFile(filePath, fileItem.data) return { url: `/uploads/${fileName}` } })
4. 前端上传组件示例
实现简单的文件上传交互,调用上述接口:
<template> <input type="file" accept="image/*" @change="handleFileUpload" /> </template> <script setup> const handleFileUpload = async (e) => { const file = e.target.files?.[0] if (!file) return const formData = new FormData() formData.append('file', file) try { const res = await fetch('/api/upload', { method: 'POST', body: formData }) const data = await res.json() console.log('文件上传完成,访问地址:', data.url) } catch (err) { console.error('上传失败:', err) } } </script>
生产环境注意事项
- 静态托管平台限制:如果部署在 Vercel、Netlify 等无服务器平台,本地文件系统是临时的,不能持久化存储上传文件,需改用云存储服务(如 AWS S3、阿里云 OSS),此时上传接口需调整为直接上传到云存储并返回云存储 URL。
- 安全防护:限制上传文件的类型、大小;添加用户鉴权,避免未授权上传;对上传文件进行病毒扫描,防止恶意文件。
内容的提问来源于stack exchange,提问作者Anton Platonov
相关产品推荐
相关产品推荐

