For DevelopersDecember 17, 2024

JavaScript POST Request: How to Send Data with Fetch, Axios & XMLHttpRequest

Discover how to send data as variables in JavaScript POST requests using different techniques.

How do you send a POST request in JavaScript? 

Use the Fetch API with method: 'POST' to send data to a server. Here's the simplest example:

javascript
fetch('https://api.example.com/data', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'John', email: '[email protected]' })
})
.then(response => response.json())
.then(data => console.log(data));

This guide covers three methods for making JavaScript POST requests: the modern Fetch API (recommended), Axios library, and legacy XMLHttpRequest. Each includes copy-paste code examples for JSON data, form submissions, and file uploads.

Building web applications that communicate with APIs? See our guide to hiring JavaScript developers through Index.dev.

 

JavaScript POST Request: Quick Reference

Method

Syntax

Best For

Browser Support

Fetch API

fetch(url, {method: 'POST'})

Modern apps, async/await

All modern browsers

Axios

axios.post(url, data)

React/Vue apps, interceptors

All (with library)

XMLHttpRequest

xhr.open('POST', url)

Legacy browser support

All browsers

Quick Copy-Paste Examples:

javascript
// Fetch API (recommended)
fetch(url, { method: 'POST', body: JSON.stringify(data) });

// Axios
axios.post(url, data);

// XMLHttpRequest
xhr.open('POST', url); xhr.send(JSON.stringify(data));

 

Understanding HTTP POST Requests in JavaScript

The HTTP POST request is one of the most popular ways for a client to deliver data to a server. Unlike GET requests, which contain parameters in the URL and are often restricted in size, POST requests convey data in the body, making them excellent for dealing with huge payloads or sensitive information.

POST requests are used when a client wants to submit data, such as filling out a form, uploading files, or engaging with a remote server API. It is more secure than GET since no data is accessible in the URL. However, security protocols such as HTTPS should always be utilized.

JavaScript POST Request Structure

A POST request has two main parts:

  • Headers provide information about the type of data being transmitted. The most frequent header is Content-Type, which may be changed to various values such as application/json or application/x-www-form-urlencoded.
  • Body: The data being sent to the server, which might be JSON, form data, or another sort of data format.

To send POST requests, you may use either the older XMLHttpRequest method or the newer Fetch API, which is easier and delivers promises.

 

Sending Data Using XMLHttpRequest

XMLHttpRequest is the usual method for making HTTP requests in JavaScript. Even though the Fetch API is currently favored, understanding XMLHttpRequest can still be useful in legacy projects.

Creating an XMLHttpRequest

var xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com/api", true);
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function() {
  if (xhr.readyState == 4 && xhr.status == 200) {
    console.log(xhr.responseText);
  }
};

var data = JSON.stringify({
  "name": "John Doe",
  "email": "[email protected]"
});

xhr.send(data);

In the example above:

  • We construct an instance of XMLHttpRequest.
  • We connect to the server using the POST method and provide the Content-Type as application/json.
  • The data is stringified and sent in the request's body.

 

JavaScript POST Request with Fetch API

The Fetch API is the modern, recommended way to make HTTP requests in JavaScript. It's built into all modern browsers and uses Promises for clean async handling.

Basic Fetch POST Request:

javascript
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: '[email protected]'
  })
})
.then(response => response.json())
.then(data => console.log('Success:', data))
.catch(error => console.error('Error:', error));

Fetch POST with async/await:

javascript
async function sendPostRequest() {
  try {
    const response = await fetch('https://api.example.com/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        name: 'Jane Doe',
        email: '[email protected]'
      })
    });
   
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
   
    const data = await response.json();
    console.log('Success:', data);
    return data;
  } catch (error) {
    console.error('Error:', error);
  }
}

sendPostRequest();

Fetch POST with Error Handling:

javascript
async function postData(url, data) {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data)
    });
   
    // Check if response is OK (status 200-299)
    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.message || 'Request failed');
    }
   
    return await response.json();
  } catch (error) {
    console.error('POST request failed:', error);
    throw error;
  }
}

// Usage
postData('https://api.example.com/users', { name: 'John' })
  .then(data => console.log(data));

Key Fetch POST Parameters:

Parameter

Description

Example

method

HTTP method

'POST'

headers

Request headers

{'Content-Type': 'application/json'}

body

Request payload

JSON.stringify(data)

credentials

Cookie handling

'include' or 'same-origin'

mode

CORS mode

'cors''no-cors''same-origin'

 

JavaScript POST Request with Axios

Axios is a popular HTTP client library that simplifies POST requests with automatic JSON transformation, better error handling, and request interceptors.

Install Axios:

bash
npm install axios
# or
yarn add axios
# or CDN
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Basic Axios POST Request:

javascript
import axios from 'axios';

axios.post('https://api.example.com/users', {
  name: 'John Doe',
  email: '[email protected]'
})
.then(response => console.log('Success:', response.data))
.catch(error => console.error('Error:', error));

Axios POST with async/await:

javascript
import axios from 'axios';

async function createUser(userData) {
  try {
    const response = await axios.post('https://api.example.com/users', userData);
    console.log('User created:', response.data);
    return response.data;
  } catch (error) {
    if (error.response) {
      // Server responded with error status
      console.error('Server error:', error.response.data);
    } else if (error.request) {
      // Request made but no response
      console.error('Network error:', error.request);
    } else {
      console.error('Error:', error.message);
    }
    throw error;
  }
}

// Usage
createUser({ name: 'Jane', email: '[email protected]' });

Axios POST with Custom Headers:

javascript
axios.post('https://api.example.com/data', 
  { message: 'Hello' },
  {
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json',
      'X-Custom-Header': 'custom-value'
    }
  }
);

Axios vs Fetch Comparison:

Feature

Axios

Fetch

Auto JSON parsing

✅ Yes

❌ Manual .json()

Error on 4xx/5xx

✅ Yes

❌ Manual check

Request interceptors

✅ Yes

❌ No

Request timeout

✅ Built-in

❌ Manual AbortController

Bundle size

~13KB

0KB (native)

Browser support

All (with polyfill)

Modern only

For React-based applications, see our guide on React developer hourly rates when building your frontend team.

 

JavaScript POST Request with XMLHttpRequest (Legacy)

XMLHttpRequest is the traditional method for making HTTP requests. While Fetch is preferred for new projects, XMLHttpRequest is still useful for legacy browser support.

Basic XMLHttpRequest POST:

javascript
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      const response = JSON.parse(xhr.responseText);
      console.log('Success:', response);
    } else {
      console.error('Error:', xhr.status, xhr.statusText);
    }
  }
};

const data = JSON.stringify({
  name: 'John Doe',
  email: '[email protected]'
});

xhr.send(data);

XMLHttpRequest POST with Callbacks:

javascript
function postRequest(url, data, onSuccess, onError) {
  const xhr = new XMLHttpRequest();
  xhr.open('POST', url, true);
  xhr.setRequestHeader('Content-Type', 'application/json');
 
  xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 300) {
      onSuccess(JSON.parse(xhr.responseText));
    } else {
      onError(xhr.status, xhr.statusText);
    }
  };
 
  xhr.onerror = function() {
    onError(0, 'Network error');
  };
 
  xhr.send(JSON.stringify(data));
}

// Usage
postRequest(
  'https://api.example.com/users',
  { name: 'John' },
  (data) => console.log('Success:', data),
  (status, message) => console.error('Error:', status, message)
);

 

Send FormData with JavaScript POST Request

Use FormData for file uploads and multipart form submissions. FormData automatically sets the correct Content-Type header.

FormData with Fetch:

javascript
const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('email', '[email protected]');
formData.append('avatar', fileInput.files[0]); // File upload

fetch('https://api.example.com/upload', {
  method: 'POST',
  body: formData  // Don't set Content-Type header!
})
.then(response => response.json())
.then(data => console.log('Uploaded:', data));

FormData from HTML Form:

javascript
const form = document.getElementById('myForm');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
 
  const formData = new FormData(form);
 
  try {
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData
    });
    const result = await response.json();
    console.log('Form submitted:', result);
  } catch (error) {
    console.error('Submission failed:', error);
  }
});

FormData with Axios:

javascript
const formData = new FormData();
formData.append('file', selectedFile);

axios.post('/api/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  },
  onUploadProgress: (progressEvent) => {
    const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
    console.log(`Upload progress: ${percent}%`);
  }
});

 

Common JavaScript POST Request Patterns

1. POST with Authentication Token:

javascript
async function authenticatedPost(url, data, token) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify(data)
  });
  return response.json();
}

2. POST with URL-encoded Data:

javascript
const params = new URLSearchParams();
params.append('username', 'john');
params.append('password', 'secret');

fetch('/api/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: params
});

3. POST with Timeout (AbortController):

javascript
async function postWithTimeout(url, data, timeoutMs = 5000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
 
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    return await response.json();
  } catch (error) {
    if (error.name === 'AbortError') {
      throw new Error('Request timed out');
    }
    throw error;
  }
}

4. Reusable POST Function:

javascript
async function post(url, data, options = {}) {
  const config = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      ...options.headers
    },
    body: JSON.stringify(data),
    ...options
  };
 
  const response = await fetch(url, config);
 
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
 
  return response.json();
}

// Usage
const user = await post('/api/users', { name: 'John' });

 

Sending Data as URL Encoded Variables

When delivering data as URL-encoded variables (often used in forms), the Content-Type must be set to application/x-www-form-urlencoded. This format is suitable for basic text data.

Example of URL-encoded data

const data = new URLSearchParams();
data.append('username', 'johndoe');
data.append('password', 'securepassword');

fetch('https://example.com/api/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: data.toString(),
})
.then(response => response.json())
.then(data => console.log('Logged in:', data))
.catch(error => console.error('Error:', error));

URLSearchParams is used to generate the query string, which is subsequently given as the request body. This method is lighter weight than transmitting JSON, making it appropriate for delivering basic key-value pairs.

 

Handling Response Data

Handling the server's response is just as crucial as delivering data via a POST request. You may wish to parse the answer (which is often JSON) and handle any potential issues.

Parsing JSON Responses with Fetch

fetch('https://example.com/api', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ message: 'Hello, server!' })
})
.then(response => {
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
})
.then(data => console.log('Response received:', data))
.catch(error => console.error('Error:', error));

The response is verified for status using respond.ok. If successful, it is parsed using.json(). This approach ensures that both success and error instances are handled properly.

 

Advanced Techniques

Sending files using POST requests

As previously demonstrated, using FormData allows you to simply transmit files. This approach is crucial for developing applications that need picture or document uploads, such as a content management system.

Cross-origin POST requests and CORS

When sending POST requests across domains, the server must support Cross-Origin Resource Sharing. CORS is a security feature in browsers that prevents unwanted interactions between domains. Make that the server contains proper headers, such as Access-Control-accept-Origin, to accept requests from your domain.

 

Conclusion

JavaScript POST requests are fundamental for sending data to servers in web applications. Here's when to use each method:

Quick Recommendations:

Scenario

Use This

Modern web apps

Fetch API with async/await

React/Vue projects

Axios for interceptors & error handling

File uploads

FormData with Fetch or Axios

Legacy browser support

XMLHttpRequest or Axios with polyfill

Simple scripts

Fetch API (zero dependencies)

Key Takeaways:

  • Fetch API is recommended for most use cases—it's native and Promise-based
  • Axios simplifies error handling and is great for complex apps with interceptors
  • Always set Content-Type: application/json when sending JSON data
  • Use FormData for file uploads (don't set Content-Type manually)
  • Implement proper error handling with try/catch or .catch()

Building JavaScript applications? Hire senior JavaScript developers through Index.dev — our network includes engineers experienced in modern JavaScript, React, Node.js, and API development.

For JavaScript Developers:

Looking to work on advanced JavaScript projects? Join Index.dev for high-paying remote jobs with top global companies today!

For Clients:

Need expert JavaScript developers to build dynamic web apps? Hire vetted talent from Index.dev’s global network now!

Frequently Asked Questions

Book a consultation with our expert

Hero Pattern

Share

Radhika VyasRadhika VyasCopywriter

Related Articles

For DevelopersWhat If AI Could Tell QA What Your Pull Request Might Break?
Software Development
QA engineers face high-pressure decisions when a new pull request arrives—what should be tested, and what could break? This blog shows how AI can instantly analyze PR diffs, highlight affected components, and suggest test priorities.
Mehmet  Serhat OzdursunMehmet Serhat Ozdursunauthor
For EmployersHow Specialized AI Is Transforming Traditional Industries
Artificial Intelligence
Artificial intelligence is changing how traditional industries work. Companies are no longer relying only on general skills. Instead, they are using AI tools and specialized experts to improve productivity, reduce costs, and make better decisions.
Ali MojaharAli MojaharSEO Specialist