My objective involves uploading image and video files to the /public/uploads directory through a form on my Index.tsx. I am utilizing Multer in my API Endpoint to accomplish this task.
Unfortunately, a peculiar issue arises when attempting to upload files larger than 195KB: they are consistently truncated at exactly 195KB, leading to corrupted video files and incomplete image uploads. Despite setting the limit to 100MB, files exceeding 195KB fail to be uploaded successfully.
upload.js
import multer from 'multer';
import path from 'path';
const upload = multer({
storage: multer.diskStorage({
destination: path.join(process.cwd(), 'public/uploads'),
filename: (req, file, callback) => {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const originalExtension = path.extname(file.originalname);
const newFileName = `${year}_${month}_${day}-${hours}h_${minutes}m_${seconds}s-${file.originalname}`;
callback(null, newFileName);
},
}),
limits: {
fileSize: 1000 * 1024 * 1024, // 100MB limit
},
});
export const config = {
api: {
bodyParser: false,
timeout: 0,
responseLimit: false,
},
};
export default async function handler(req, res) {
if (req.method === 'POST') {
try {
await upload.single('image')(req, res);
res.status(200).json({ message: 'File uploaded successfully' });
} catch (error) {
console.error('Error uploading file:', error);
res.status(500).json({ error: 'Error uploading file' });
}
} else {
res.status(405).json({ error: 'Method Not Allowed' });
}
}
Index.tsx:
import React, { useState, useEffect } from "react";
function Index() {
const [image, setImage] = useState<any>(null);
const currentDate = new Date().toISOString().split("T")[0];
const handleFileChange = (event) => {
const file = event.target.files[0];
setImage(file);
};
const handleSubmit = async () => {
if (!image) {
console.error("No file selected");
return;
}
const formData = new FormData();
formData.append("image", image);
try {
const response = await fetch("/api/upload", {
method: "POST",
body: formData,
});
if (response.ok) {
console.log("File uploaded successfully");
} else {
console.error("Error uploading file:", response.statusText);
}
} catch (error) {
console.error("Error uploading file:", error);
}
};
return (
<>
<section className="text-gray-400 body-font relative">
<div className="container px-5 py-24 mx-auto">
<div className="flex flex-col text-center w-full mb-12">
<h1 className="sm:text-3xl text-2xl font-medium title-font mb-4 text-white">
Upload Files
</h1>
<p className="lg:w-2/3 mx-auto leading-relaxed text-base">
Upload your image
</p>
</div>
<div className="lg:w-1/2 md:w-2/3 mx-auto">
<div className="flex flex-wrap -m-2">
<div className="p-2 w-full">
<div className="relative">
<label className="custom-file-upload w-full bg-gray-500 bg-opacity-40 rounded border border-gray-700 focus:border-teal-500 focus:bg-gray-700 focus:ring-2 focus:ring-teal-900 h-16 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out">
<input
type="file"
accept=".jpg, .jpeg, .png, .mov, .mp4"
multiple={false}
onChange={handleFileChange}
id="image"
name="image"
className=" hidden w-full bg-opacity-40 rounded border border-gray-700 focus:border-teal-500 focus:bg-gray-700 focus:ring-2 focus:ring-teal-900 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
></input>
Choose File
</label>
{image && (
<div className="py-2">
{image.type.startsWith("image/") ? (
<img
src={URL.createObjectURL(image)}
alt="Uploaded Image"
className="border rounded-lg"
style={{ width: "250px", height: "250px" }}
/>
) : (
<video
src={URL.createObjectURL(image)}
controls
className="border rounded-lg"
></video>
)}
<p>Selected file: {image.name}</p>
</div>
)}
</div>
</div>
<div className="p-2 w-full">
<button
className="mt-6 flex mx-auto text-white bg-teal-500 border-0 py-2 px-8 focus:outline-none hover:bg-teal-600 rounded text-lg"
onClick={handleSubmit}
>
Upload
</button>
</div>
</div>
</div>
</div>
</section>
</>
);
}
export default Index;
I attempted adjusting the limit within the multer object without success. Furthermore, I modified my api configuration to include:
responseLimit: false
However, these modifications proved ineffective as the file upload restriction persisted at 195KB.