Nextjs14 + Minio实现文件的上传下载
事先准备
初始化nextjs项目
搭建minio服务 (docker一分钟搞定 下面是链接)
https://nextjs.org/docs/getting-started/installation
Docker 搭建 Minio 容器 (完整详细版)_docker minio-CSDN博客
第一步
下载minio客户端
yarn add minio
或者
npm i minio
第二步
随便找个顺眼的文件夹 我是放在lib文件夹下面 起名 file-uploader 供后面接口编写引入
切记秘钥啥的放 .env文件里用以下方式导入 .gitignore 文件里也别忘了配置,别把 .env文件
也提交上去了 还有该文件不要在 "use client"也就是客户端渲染的文件里面引入(那样一样会暴露你的敏感信息)
本人因为不小心提交阿里巴巴oss秘钥到github导致泄露 所以对于敏感信息比较谨慎
const Minio = require('minio');
export const minioClient = new Minio.Client({
endPoint: process.env.NEXT_PUBLIC_MINIO_END_POINT,
port: parseInt(process.env.NEXT_PUBLIC_MINIO_PORT!),
useSSL: process.env.NEXT_PUBLIC_MINIO_USE_SSL === 'true',
accessKey: process.env.NEXT_PUBLIC_MINIO_ACCESS_KEY,
secretKey: process.env.NEXT_PUBLIC_MINIO_SECRET_KEY,
});
[!NOTE]
这里有个小坑
如果我使用 ES6 的模块导入语法的话
像这样 import Minio from “minio”
就报错说 Minio is undefined
知道为什么的兄弟评论下方告诉我一下 谢谢
第三步
下载下mime(获取文件后缀名)
yarn add mime
编写上传文件接口 (写到/app/api/)路径下即可 名字随意
import mime from 'mime';
import { minioClient } from '@/lib/file-uploader';
export async function POST(req: Request) {
const formData = await req.formData();
const file = formData.get('file') as Blob | null;
if (!file) {
return NextResponse.json({ error: 'field file not empty' }, { status: 400 });
}
const buffer = Buffer.from(await file.arrayBuffer());
try {
// 如果想要在指定文件夹下储存该图片 直接加上前缀即可 我这里加了个/image
const url = `/image/${自定义文件名}.${mime.getExtension(file.type)}`;
await minioClient.putObject('blog-dashboard', url, buffer);
return NextResponse.json({ url });
} catch (error) {
console.log('UPLOAD_POST', error);
return new NextResponse('Internal Error', { status: 500 });
}
}
最后编写下载接口
import { minioClient } from '@/lib/file-uploader';
import { NextResponse } from 'next/server';
export async function GET(req: Request, { params }: { params: { fileName: string } }) {
const blob = await minioClient.getObject('blog-dashboard', `/image/${params.fileName}`);
const headers = new Headers();
// headers.set('Content-Type', 'image/*'); 默认动作是下载
headers.set('content-Type', 'text/plain'); // 默认动作是浏览器展示
return new NextResponse(blob, { status: 200, statusText: 'OK', headers });
}