Multer in NextJS having trouble uploading complete files (stopping at 195KB)

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.

Answer №1

I apologize for the inconvenience, but I have discovered the resolution:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Background Disappears Following Website Relocation

Recently, I created a PowerPoint presentation and then converted it to HTML using the conversion tool available at . The result on their website is exactly what I wanted, with a perfect layout. However, when I downloaded the zip file and uploaded the conte ...

The route information is not appearing on the screen

I am facing an issue with my application's route called home. The content on this route is not being displayed; instead, only the menu from app.component is shown. I believe I might be overlooking something obvious. Can someone assist me with this pro ...

Tips for showcasing a string value across various lines within a paragraph using the <br> tag for line breaks

I'm struggling to show a string in a paragraph that includes tags to create new lines. Unfortunately, all I see is the br tags instead of the desired line breaks. Here is my TypeScript method. viewEmailMessage(messageId: number): void { c ...

Using a URL parameter inside an AJAX call

Greetings! I am looking to incorporate an ajax function for data transfer to my php page while utilizing the $_GET variable for verification purposes. This is the code snippet that I have implemented: $.ajax({ type: "POST", url: "coords ...

Refreshing the view following a model update within an AJAX call in the Backbone framework

I'm struggling with my code as I can't seem to get my view to update after a model change. var ResultLoanView = Backbone.View.extend({ id:"result", initialize: function(){ this.render(); this.on('submissionMa ...

Issue with Angular ngFor within a particular dialog window?

(respPIN and internalNotes are both of type InternalNotes[]) When the code in encounter.component.ts is set like this: this.ps.GetInternalNotes(resp.PersonID.toString()).subscribe(respPIN => { this.internalNotes = respPIN; }); An ERROR occurs: Err ...

Incorporating Material-UI with React Searchkit for a seamless user experience, featuring

I encountered an issue when trying to use both searchkit and material-ui in my React application. The problem arises from the fact that these two libraries require different versions of reactjs. Initially, everything was working fine with just searchkit in ...

What is the best way to use ajax for uploading multiple images at once?

I'm having trouble uploading multiple image files. Can someone please review my code? <form id="fileupload" method="POST" enctype="multipart/form-data"> <input type="file" name="files[]" multiple="multiple" id="images_input"> & ...

Issue: Unresolved TypeError: Unable to extract 'title' property from 'list' object because it is not defined

I implemented axios to fetch data from my mongoDB database, aiming to use it in my code for displaying information on the React frontend. However, I am encountering an issue where my React front end appears blank and an error message pops up saying 'U ...

Using JSX to apply conditional statements in a map iteration

I'm grappling with the concept of implementing conditional statements within JSX. I have an array of objects that I am iterating through to create a select box. My goal is to omit items that contain the word "threshold" in indicator.name. However, u ...

Executing multiple AJAX requests with promises in Angular based on an array of values

I have been working on implementing multiple ajax calls in sequence using Angular. Interestingly, everything seems to be working fine when I use $.ajax, but when I switch to using $http for server requests in Angular, things start to go awry. Both methods ...

The Typescript Vue component failed to mount because the template or render function was not defined

Hey everyone, I recently decided to incorporate TypeScript into my Vue project. After successfully compiling without any errors, I encountered a console error message when opening the page: vue.runtime.esm.js?2b0e:619 [Vue warn]: Failed to mount component: ...

`Is there a way to retrieve data from an array of Input elements using PHP?`

I am currently working on implementing a contact form using J Query, PHP AJAX. In the code snippet below, I am gathering form information and sending it to the server using a for loop and an array of form inputs. As someone who is new to this type of co ...

What distinguishes a WAV file recorded from a user's microphone versus a WAV file imported from a separate file? Identifying the unique characteristics that may be causing bugs

Currently, I have two methods available for sending a WAV file to the server. Users can either upload the file directly or record it using their microphone. After the files are sent, they undergo a similar processing workflow. The file is uploaded to S3 an ...

Is there a variety of values for the POST value field?

Currently, I am working on a contact edit form. The entire form loads dynamically via ajax, appearing in a lightbox. The form is pre-populated with the existing contact's data. After clicking the edit button, jQuery scans for any changes in the for ...

Replacing a string in a textarea using Jquery

Trying to dynamically replace a string value in a textarea while typing into a textbox using jQuery. Utilizing the keypress event for this functionality. Any ideas on what could be causing issues with this example? <input type="text" id="textbox" /> ...

Force Layout - Labeling and anchoring the nodes

Currently I am creating my own force drag feature using d3js. I stumbled upon a fantastic example here which covers most of what I need: However, I have encountered a problem that I am struggling to solve due to my limited knowledge of d3js. I am attempt ...

Communication between the content script and background page in a chrome extension is not functioning correctly as intended

Displayed below is the code I posted: manifest.json { "manifest_version": 2, "name": "Demo", "description": "all_frames test", "version": "1.0", "background": { "scripts": ["background.js"] }, "content_scripts": [{ "matches": ...

The active class in the navbar is malfunctioning in Bootstrap 4

I've been searching high and low to figure out how to add an active class to the current open link in my navbar. I've scoured Google and Stack Overflow for answers, but everything I found only applies to hash-type navbars using href="#". None of ...

The Same Origin Policy has prevented access to the remote resource located at http://localhost:8082/api/countries due to a Cross-Origin Request Block

Solution The XMLHttpRequest access to 'http://localhost:8082/api/countries' from the origin 'http://localhost:4200' has been blocked by the CORS policy. The response to the preflight request is failing the access control check because t ...