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

Instructions on obtaining information from these input fields

I'm currently working on creating an attendance page and I need help figuring out how to fetch data from the inputs. Specifically, I'm looking for guidance on how to name the inputs in order to retrieve the data from hidden and radio inputs. Her ...

Tips for effectively interpreting a json string

Trying to extract specific fields from a JSON string and display them on an HTML page, but encountering the following error: SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data This is the JSON being sent: { "Order0& ...

What is the proper method for setting up handlers in functional React components?

My knowledge of JavaScript tells me that there are three different ways to define functions. Let's take a look at them: 1. Declaration function handleEvent(e) {} 2. Assignment var handleEvent = function(e) {} 3. Arrow var handleEvent = (e) => ...

Implementing Bootstrap in Angular 2 using vanilla JavaScript/ES6: A step-by-step guide

Currently, I am in the process of developing an Angular 2 application without TypeScript and facing difficulties with bootstrapping it as I cannot find any relevant examples. My app, which does not include the bootstrap() function, starts off like this: ...

Sending C# Model from View to Javascript

I have set up my ViewModel for the View: public class DashboardViewModel { public List<UserTask> UserTasks {get; set;} public List<WorkItem> WorkItems {get; set;} } In the View, I am looping through the WorkItems as follows: ...

Choosing particular contenteditable divisions using jQuery

Consider the following HTML structure for a specific type of blog post editor: <div class="entry"> <div class="title" contenteditable="true"> <h2>Title goes here</h2> </div> <div class="content" contenteditable ...

Using AngularJS to make repeated API calls with modified parameters

Issue - My task involves consolidating the response array into one. I am making consecutive calls to the same API, with a dynamic 'skip' parameter based on the last response. Call #1 - api(id, skip=0) Call #2 - api(id, skip+1) ... Below is the ...

Can someone explain the meaning of this code?

Recently, I came across a project where this line of code was used in a jQuery script. I'm not sure of its purpose and would appreciate some help understanding why it was included. If necessary, I can provide the entire function for reference. $("#ta ...

When a user connects to Node.js using sockets, the previous messages are loaded. However, a bug causes the messages to be loaded to all chat users, instead of just the

New to node.js, I am currently creating a chat application with two main files: server.js (server side) and script.js (client side). In the server.js file: socket.on('previousMessages', function (data){ db.query("SELECT * FROM messages", f ...

The Jquery AjaxFileupload feature seems to only function properly when I am running it

Below is the code snippet from my controller: function upload() { //initialize variables $status = ""; $msg = ""; $file = ""; $config = array( 'upload_path' => './uploads/product_images/full/', & ...

Looking to merge two components into one single form using Angular?

I am currently developing an Angular application with a dynamic form feature. The data for the dynamic form is loaded through JSON, which is divided into two parts: part 1 and part 2. // JSON Data Part 1 jsonDataPart1: any = [ { "e ...

Choosing items by pressing "shift + up arrow"

I have a collection of elements, each representing one line of text. When you click on an element, it changes color. If you then hold down "shift + arrow up," the items above it are also selected. How can this functionality be implemented? My initial app ...

Creating a Navigation Bar in Outlook Style Using Javascript and CSS

Looking for a navigation sidebar design similar to Outlook for my web application. I have seen options available as Winform controls and through Visual WebGUI, but these are Microsoft-dependent solutions. We need a Javascript & CSS based solution that is s ...

Update data dynamically on a div element using AngularJS controller and ng-repeat

I am currently navigating my way through Angular JS and expanding my knowledge on it. I have a div set up to load data from a JSON file upon startup using a controller with the following code, but now I am looking to refresh it whenever the JSON object cha ...

Utilizing JS datepicker for multiple input fields sharing a common class

After trying to implement the js-datepicker plugin from https://www.npmjs.com/package/js-datepicker, I ran into an issue. I have multiple input fields in which I want to use the same date picker, so I assigned them all the class 'year'. Unfortuna ...

Determine the sum of all the values entered into the text fields

On my ASP.Net page, there is a screen where users can select between 1 and 5 text boxes to input an amount. Depending on certain criteria, a specific number of these edit boxes are displayed - no hiding involved. So if I choose to display 3 boxes, only 3 w ...

Using Ajax and jQuery to Retrieve the Value of a Single Tag Instead of an Entire Page

Let's say I have a webpage named page.html: <!doctype html> <html> <head> <meta charset="utf-8"> <title>Page</title> </head> <body> <h1>Hello World!!</h1> </body> </html> Now ...

What steps can be taken to enhance the functionality of this?

Exploring ways to enhance the functionality of JavaScript using the underscore library. Any ideas on how to elevate this code from imperative to more functional programming? In the provided array, the first value in each pair represents a "bucket" and the ...

Creating HTML elements using JavaScript compared to importing an HTML fileIn JavaScript,

I am currently in the process of building a website that is entirely driven by JavaScript. Aside from the index page, I do not use any HTML pages at all. Instead, I fetch JSON data for every query and then dynamically generate HTML within the JavaScript to ...

After running javascript, Elements do not retain any values

I have encountered an issue with two button click events - one is in Javascript and the other in VB. The first button (Javascript) retrieves values from various controls like textboxes and dropdown lists, while the second button (VB) saves these values to ...