返回
Next.js 13+ 文件上传新技巧:极速上手无需第三方库
后端
2023-12-21 22:53:16
Next.js 13+ 中使用 Fetch API 的文件上传指南
准备工作
踏入 Next.js 的文件上传之旅,首先需要确保已安装 Node.js 和 npm。然后,让我们创建一个新的 Next.js 项目:
npx create-next-app my-app
创建上传组件
在 pages
目录中,创建一个名为 Upload.js
的文件,用于构建我们的上传组件:
import React, { useState } from "react";
import axios from "axios";
const Upload = () => {
const [selectedFile, setSelectedFile] = useState(null);
const handleFileChange = (event) => {
setSelectedFile(event.target.files[0]);
};
const handleSubmit = (event) => {
event.preventDefault();
if (!selectedFile) return;
const formData = new FormData();
formData.append("file", selectedFile);
axios.post("/api/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
};
return (
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleFileChange} />
<button type="submit">Upload</button>
</form>
);
};
export default Upload;
创建 API 路由
在 pages/api
目录中,创建一个名为 upload.js
的文件,作为我们的 API 路由:
import { NextApiRequest, NextApiResponse } from "next";
import fs from "fs";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
res.status(405).json({ message: "Method not allowed" });
return;
}
const file = req.files?.file;
if (!file) {
res.status(400).json({ message: "No file uploaded" });
return;
}
const fileName = Date.now() + "-" + file.name;
await file.mv(`./uploads/${fileName}`);
res.status(200).json({ message: "File uploaded successfully" });
}
运行项目
是时候让引擎轰鸣了!在项目根目录下运行以下命令:
npm run dev
测试上传功能
现在,可以访问 http://localhost:3000/upload
来测试上传功能了。选择一个文件,然后点击上传按钮。如果一切顺利,您会收到一条胜利的成功消息。
常见问题解答
1. 文件上传为什么没有响应?
- 检查您的 API 路由是否正确配置,并确保已将
multipart/form-data
设置为Content-Type
标头。
2. 如何处理较大的文件上传?
- 可以使用云存储服务,如 Amazon S3 或 Google Cloud Storage,来处理大文件。
3. 如何验证上传的文件类型?
- 在服务器端代码中,使用
file.mimetype
或path.extname(file.name)
来验证文件类型。
4. 如何自定义上传文件路径?
- 在
upload.js
中,可以修改./uploads/${fileName}
以将文件存储在自定义路径中。
5. 如何实现拖放上传?
- 可以使用第三方库,如 react-dropzone,来实现拖放上传。
总结
恭喜您,您已掌握了在 Next.js 13+ 中使用 Fetch API 进行文件上传的艺术!如果您还有疑问,请随时提问。祝您在上传世界中一切顺利,期待您的杰作!