NextJS Multer没有上传完整文件(仅195KB)

huangapple go评论115阅读模式
英文:

NextJS Multer not uploading full file (only 195KB)

问题

我的目标是通过Index.tsx上的表单将图像和视频文件上传到我的/public/uploads文件夹中。为此,我在我的API端点中使用了Multer。

然而,每当我上传大于195KB的文件时,它都会在195KB处达到上限,图像文件会被截断,视频文件会损坏。我在/public/upload文件夹中看到的最大值是195KB,尽管我将限制设置为100MB。

我尝试了在Multer对象上设置限制,但仍然没有成功。我还将我的API配置更改为:

{
  "responseLimit": false
}

但仍然没有起作用。它仍然将我的文件上传限制在195KB。

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) => {
      // ...(文件名生成逻辑)
      callback(null, newFileName);
    },
  }),
  limits: {
    fileSize: 1000 * 1024 * 1024, // 100MB限制
  },
});

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: '文件上传成功' });
    } catch (error) {
      console.error('上传文件时出错:', error);
      res.status(500).json({ error: '上传文件出错' });
    }
  } else {
    res.status(405).json({ error: '不允许的方法' });
  }
}

Index.tsx文件:

import React, { useState, useEffect } from "react";

function Index() {
  // ...(其他代码)
}

export default Index;

希望这有助于解决您的问题。如果您有其他疑问,请随时提出。

英文:

My goal is to upload image and video files into my /public/uploads folder through a form on my Index.tsx. To do this, I am using Multer in my API Endpoint.

However, whenever I upload files over 195KB, it maxes out at 195KB and image files gets cut off and video files gets corrupted. The max I see in the /public/upload file was 195KB although I set the limit to 100MB.

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 tried the limit on the multer object but still had no luck. I also changed my api config to

responseLimit: false

but did not work. It still capped my file uploads to 195KB.

答案1

得分: 1

I found the solution:

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,
  },
};

export default async function handler(req, res) {
  await upload.single('image')(req, res, (error) => {
    if (error instanceof multer.MulterError) {
      // Multer error occurred
      console.error('Error uploading file:', error);
      res.status(500).json({ error: 'Error uploading file' });
    } else if (error) {
      // Other error occurred
      console.error('Error uploading file:', error);
      res.status(500).json({ error: 'Error uploading file' });
    } else {
      // File uploaded successfully
      res.status(200).json({ message: 'File uploaded successfully' });
    }
  });
}
英文:

sorry, I found the solution:

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,
},
};
export default async function handler(req, res) {
await upload.single('image')(req, res, (error) => {
if (error instanceof multer.MulterError) {
// Multer error occurred
console.error('Error uploading file:', error);
res.status(500).json({ error: 'Error uploading file' });
} else if (error) {
// Other error occurred
console.error('Error uploading file:', error);
res.status(500).json({ error: 'Error uploading file' });
} else {
// File uploaded successfully
res.status(200).json({ message: 'File uploaded successfully' });
}
});
}

huangapple
  • 本文由 发表于 2023年6月9日 13:37:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定