All file upload requests consistently result in a status code of 400

I am encountering an issue with file uploading in Express. Every time I send a request with multipart/form-data, I receive a 400 bad request response with no error message, just an empty object. Currently, I am using busboy-body-parser for parsing multipart formdata requests. I also tried using express-fileupload and faced the same problem.

Below are my request methods:

get(endpoint) {
  return this.request('GET', endpoint, null);
}

post(endpoint, body) {
  return this.request('POST', endpoint, body);
}

postFile(endpoint, file) {
  return this.request('POST', endpoint, file, contentTypes.file);
}

async request(method, endpoint, body, contentType=contentTypes.json) {
  const { authToken } = this;
  const endpointUrl = this.getEndpointUrl(endpoint);
  const headers = new Headers();

  if(authToken) {
    headers.append(authTokenHeader, authToken);
  }
  headers.append('Accept', 'application/json, application/xml, text/plain, text/html, *.*');
  headers.append('Content-Type', contentType);

  const response = await fetch(endpointUrl, {
    method: method,
    headers: headers,
    body: this._serializeRequestBody(body, contentType),
  });

  const result = await this._parseResponse(response);

  if(!response.ok) {
    if(response.status === 401) {
      this.revokeAuth();
    }
    throw result || new Error('Unknown error (no error in server response)');
  } else if(result && result.authToken) {
    this.setAuthToken(result.authToken);
  }

  return result;
}

Here is _serializeRequestBody and _parseResponse:

_parseResponse(response) {
  const contentType = response.headers.get('Content-Type').split(';')[0];
  if(contentType === contentTypes.json) {
    return response.json();
  }
  return response.text();
}

_serializeRequestBody(body, contentType) {
  if(!body) return null;
  switch(contentType) {
    case contentTypes.json:
      return JSON.stringify(body);
    case contentTypes.file:
      const formData = new FormData();
      formData.append('file', body);
      return formData;
  }
  return body;
}

And contentTypes:

const contentTypes = {
  json: 'application/json',
  file: 'multipart/form-data',
};

My express middleware is as follows:

if(this._expressLoggingMiddleware) {
  app.use(this._expressLoggingMiddleware);
}

if(this.isNotProductionEnv && this.isNotTestEnv) {
  app.use(require('morgan')('dev'));
}

// Adds `res.success` and `res.fail` utility methods.
app.use(require('./utils/envelopeMiddleware')());

// Allow cross-origin requests if `config.cors` is `true`.
if(config.cors) app.use(require('cors')());

// Parse JSON and form request bodies.
app.use(busboyBodyParser()); // parses multipart form data (used for file uploads)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// Lookup users by the JWT in their request header.
app.use(passportJWTMiddleware(passport, this.jwtSecret, jwtPayload =>
  this.lookupUserfromAuthToken(jwtPayload).catch((error) => {
    log.warn('Error while looking up user from JWT:', error);
    return null;
  })
));

// Serve files from `config.publicDir`.
if(config.publicDir) {
  log.debug(`Hosting static files in "${config.publicDir}"`);
  app.use(express.static(config.publicDir));
}

Request information can be found in Chrome's Dev Tools:

https://i.stack.imgur.com/y5Hqm.png

As well as the request payload:

https://i.stack.imgur.com/ORt70.png

And the response received:

https://i.stack.imgur.com/PZgJw.png

Answer №1

The solution turned out to be: avoid manually defining the Content-Type header as multipart/form-data because by letting the browser do it, the necessary boundary value will automatically be included in the content type.

To correct my code, I simply need to explicitly set the Content-Type header only when sending JSON:

if(contentType === contentTypes.json) headers.append('Content-Type', contentType);

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

Is it possible to create a compound editor within a cell in SlickGrid that contains two date fields

Currently, I am implementing SlickGrid with jQuery and I am interested in incorporating a compound editor within a cell similar to example 3a mentioned here. However, instead of two text fields, I would like to have two date fields. Although Example 3 dem ...

What is causing Mocha.js to be unable to locate the module?

Having trouble with mocha.js not being able to locate my path! Here's the directory structure I have set up for my node course project: ///////Root --package.json --node_modules/ --playground --server -server.js -db -models ...

What is the process of invoking a JavaScript function from Selenium?

How can I trigger a JavaScript function from Selenium WebDriver when using Firefox? Whenever I am logged into my website, I typically utilize this command in Firebug's Command Editor to launch a file upload application: infoPanel.applicationManager. ...

Using jQuery and regex to validate a long string containing lowercase letters, uppercase letters, numbers, special characters, and

Good day, I've been struggling with jquery regex and could really use some assistance. I've been stuck on this since last night and finally decided to seek help :) Here is my regex code along with the string stored in the 'exg' variabl ...

Discovering common time intervals without the date component in between

I need to identify the intersection between two time ranges, focusing solely on the time and not the date. For instance, range_1 is from 9AM to 6PM while range_2 spans from 5PM to 8AM. The times are in the 24-hour format. I have a solution that finds the o ...

jQuery does not change the scroll position of elements

I'm looking to implement a feature on my website where certain points act as "magnets" and when the user is near one of these points, the window automatically scrolls to the top. I found a jQuery plugin that does something similar which you can check ...

Tips for fading out two elements after completing a drag and drop action

Visit this Codepen for more examples - Codepen I have been developing a drag and drop feature in my application. Once the item is dropped, it transitions from red to green and fades out smoothly. The droppable element behind the draggable should also fad ...

An issue arises with the Datatables destroy function

Utilizing datatables.js to generate a report table on my page with filters. However, when applying any of the filters, the data returned has varying column counts which prompts me to destroy and recreate the table. Unfortunately, an error message pops up ...

Setting up access controls for files in Express and NodeJS

Looking for a way to upload files using my express API to a server's filesystem with root owner. Is there a method to specify the file owner and permissions upon upload, like setting owner as 'me' and access as '644'? Here is what ...

Create a division that will remain visible on the screen and allow scrolling when a certain class is

Having some trouble with a fixed class div that is not continuing to scroll after the class is removed on scroll. I've attempted to fix this issue but the div keeps getting hidden instead of continuing to scroll. If anyone has any advice or can poin ...

The data is not being successfully transmitted to the controller method through the AJAX call

In my JavaScript file, I have the following code: $(document).ready(function () { $('#add-be-submit').click(function (event) { event.preventDefault(); $.ajax({ type: 'POST', url: '/snapdragon/blog/new&apos ...

Can you explain the distinction between incorporating the Express GET method and HTTPS GET method in the provided code snippet?

const express = require("express"); const app = express(); const https = require("https"); app.get("/", function (req, res){ var url = "https://example.com"; https.get(url, function(response){ ...

Which is better for handling events - jQuery delegation or function method?

Which approach is quicker and has broader browser support? 1. Utilizing a JavaScript function such as: function updateText(newtext) { $('div#id').text(newtext); } and incorporating it into an element's onclick event: <button onc ...

A guide to incorporating a textview into a React application using the Google Maps API

Wondering how to incorporate a textview within a react-google-maps component? Successfully setting up a Google map page in React using the react-google-maps API, I've managed to insert markers and link them with polylines. import React from "react"; ...

Arrays contain multiple elements, not just a single item

Is it possible to display multiple objects in one container? For instance, I have an array let array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; array.forEach((item, index) => ( <div> <div> item 1, 2, 3 </div> <div> item 4, 5, 6 </div ...

Webstorm seems to be having trouble identifying Next.js

When I create a Next.js app using the command npx create-next-app my-app --use-npm Everything is successfully installed, but when using WebStorm, I noticed that it does not auto import the <Link> component from Next.js. I have to manually import it ...

Include a description in the cell of the table

I am struggling with adding a small description below one of the columns in my three-column table. I have tried using Grid, but so far, nothing has worked for me. Can anyone provide assistance? To give you a better idea, I have highlighted the desired res ...

MUI: How can I resolve the issue of TextField not supporting the number type with maxLength restriction?

I am currently facing an issue with applying maxLength to the TextField component when the type is set to number. Here is my code snippet: const CustomTextField = ({ label, value, maxLength, required, disabled, handleChange, ha ...

"Modifying a variable within an object while iterating through a loop

I am attempting to update a variable within an object while looping through the elements. Specifically, I am targeting all parent elements with the class "parent" to use with the ScrollMagic plugin. Here is my code: var childElement = $('.child' ...

Transfer the values selected from checkboxes into an HTML input field

I am attempting to capture the values of checkboxes and then insert them into an input field once they have been checked. Using JavaScript, I have managed to show these values in a <span> tag successfully. However, when trying to do the same within a ...