Navigation

Node.js

How to Parse JSON and URL-encoded Data in Express

Parse JSON and form data in Express.js with built-in middleware. Handle POST requests with different content types using express.json() and express.urlencoded().

Table Of Contents

Problem

You need to parse incoming request bodies in different formats - JSON data from API calls and URL-encoded data from HTML forms - in your Express.js application.

Solution

const express = require('express');
const app = express();

// Parse JSON bodies (Content-Type: application/json)
app.use(express.json({ limit: '10mb' }));

// Parse URL-encoded bodies (Content-Type: application/x-www-form-urlencoded)
app.use(express.urlencoded({ 
  extended: true,  // Use qs library for parsing
  limit: '10mb'
}));

// Handle JSON data
app.post('/api/users', (req, res) => {
  console.log('JSON body:', req.body);
  
  const { name, email, age } = req.body;
  
  res.json({
    message: 'User created from JSON',
    user: { name, email, age },
    contentType: req.get('Content-Type')
  });
});

// Handle form data
app.post('/users/form', (req, res) => {
  console.log('Form body:', req.body);
  
  const { name, email, age } = req.body;
  
  res.json({
    message: 'User created from form',
    user: { name, email, age },
    contentType: req.get('Content-Type')
  });
});

// Handle both types in one route
app.post('/users', (req, res) => {
  const contentType = req.get('Content-Type');
  
  if (!req.body || Object.keys(req.body).length === 0) {
    return res.status(400).json({ 
      error: 'Request body is required' 
    });
  }
  
  const { name, email, age } = req.body;
  
  res.json({
    message: 'User created successfully',
    user: { name, email, age },
    receivedAs: contentType?.includes('json') ? 'JSON' : 'Form data'
  });
});

// Raw body parser for specific routes
app.post('/webhook', express.raw({ type: 'application/octet-stream' }), (req, res) => {
  console.log('Raw body:', req.body); // Buffer object
  res.status(200).send('Webhook received');
});

// Text body parser
app.post('/text', express.text({ type: 'text/plain' }), (req, res) => {
  console.log('Text body:', req.body); // String
  res.json({ received: req.body });
});

// Error handling for malformed JSON
app.use((err, req, res, next) => {
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
    return res.status(400).json({ 
      error: 'Invalid JSON in request body' 
    });
  }
  next();
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Test with different content types:

# JSON request
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John","email":"john@example.com","age":30}'

# Form request
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "name=John&email=john@example.com&age=30"

Explanation

express.json() parses incoming requests with JSON payloads and populates req.body. express.urlencoded() handles form submissions with extended: true using the qs library for nested objects.

Both middleware functions only parse requests with matching Content-Type headers. The limit option prevents large payloads from overwhelming your server. Always add error handling for malformed JSON to provide better user feedback.

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Node.js