javascriptnode.jsexpressxmlhttprequestes6-modules

Cannot send data to Node Express after converting from CJS to ESM


After having carefully converted my JS code for NodeJS from CJS to ESM (with some unexpected difficulties), I am failing to send a body content to my Node Express web server, running for test purposes on my same computer.

My project has before had success in this, both with Node Express as described, and also on the real web, run by Apache2 served by PM2 and Node Express. I have tried to follow the advices and recommendations I've found.

For the browser, this is an excerpt from the JS code at present

...
var srchData = new FormData();
srchData.append("like", str);
srchData.append("cols", searchWhere);
...
return new Promise((resolve, reject) => {
  let xhr = new XMLHttpRequest();
  xhr.open('POST', 'search/', true, null, null);
  xhr.setRequestHeader('accepts', 'application/json');
  xhr.onload = function() {
    if (this.status >= 200 && this.status < 300) {
      ...
    } else {
      ...
    }
  }
  xhr.send(srchData);
});
...

and, for the Express server (server.js), a corresponding excerpt is

import express from 'express'
...
const app = express()
app.use(express.json())
export default app
import routes from './app/routes.js'
routes(app)
...
const port = process.env.PORT || 3000
app.use('/', express.static('public'))
app.listen(port)

and (app/routes.js)

import path from 'node:path'
import { access, writeFile, readFile, readdir, open } from 'node:fs/promises'
import fs from 'node:fs'
import multer from 'multer'
import bodyParser from 'body-parser'
import util from 'util'
...
export default function(app) {
  ...
  app.post ('/search', async function(req, res, next) {
    console.log("req.body =", req.body) // *prints undefined*
    ...
  })
...
}
...

The comment prints undefined is where the problem is seen.

Please tell if more information is needed in order to understand the problem.


Solution

  • The problem is not with CJS/ESM, or sending data to the server, but with processing it on the server.

    The frontend code's srchData is FormData, so you're sending multipart/form-data request, but on your route handler you apparently don't have any middleware to process it, hence the undefined.

    You need to configure and use multer middleware from your code to process such request, for example, .none() method will process text-only multipart form (see multer docs), and you should see the body:

    app.post ('/search', multer().none(), async function(req, res, next) {
    

    FormData is usually used to send files, and if you're not sending any files, you might simply use JSON request instead, and app.use(express.json()) from your code will process it:

    var srchData = JSON.stringify({like:str, cols: searchWhere});
    //...
    xhr.setRequestHeader('Content-Type', 'application/json');
    
    xhrx.send(srchData);