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

7tofc5zh  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(146)

我的目标是通过Index. tsx上的一个表单将图像和视频文件上传到我的/public/uploads文件夹中。为此,我在我的API端点中使用Multer。
然而,每当我上传超过195 KB的文件时,它会在195 KB处最大化,图像文件会被切断,视频文件会被损坏。我在/public/upload文件中看到的最大值是195 KB,尽管我将限制设置为100 MB。
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;

我尝试了对multer对象的限制,但仍然没有运气。我还将我的API配置更改为

responseLimit: false

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

5cnsuln7

5cnsuln71#

对不起,我找到了解决方案:

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' });
    }
  });
}

相关问题