JavaScriptBrowser APIs

FormData

Collects form field values into name-value pairs. The ready-made object can be read or sent to the server with fetch().

Returns
A new FormData object.
On this page

Example

#
JavaScript
const form = document.querySelector('#signup')
const data = new FormData(form)

console.log(data.get('nick'))
console.log(data.get('course'))
console.log(data.get('newsletter'))
console.log(data.get('code'))
console.log(Object.fromEntries(data))
Console
Emma
js
on
null
{ nick: 'Emma', course: 'js', newsletter: 'on' }

A checked checkbox with no value attribute has the value "on". The disabled code field isn’t included in the data at all, so get() returns null for it.

Definition and usage

#

The new FormData(form) constructor reads every field in a form that has a name attribute and saves them as name-value pairs. You don’t need to fetch each field separately: text from text fields, checked checkboxes, selected list options, and files all land in a single object. Disabled fields (disabled) and unchecked checkboxes are skipped.

The get(name) method returns a field’s value (a string or a file) or null, getAll() returns every value under a given name, e.g. from several checked checkboxes, and has(), set(), append(), and delete() let you check and change the data. Object.fromEntries(formData) turns it into a plain object, but for repeated names only the last value survives.

A FormData object passed as the body to fetch() is sent in multipart/form-data format, the same one a regular form with files uses. Don’t set the Content-Type header by hand in that case, because the browser needs to add a boundary that separates the fields to it. If the server expects JSON, convert the data to a plain object and send it with JSON.stringify().

Syntax

#
Syntax
new FormData()
new FormData(form)
new FormData(form, submitter)

formData.get(name)
formData.getAll(name)
formData.has(name)
formData.set(name, value)
formData.append(name, value)
formData.delete(name)

Parameters

#
  • form

    optional, <form> element

    The form whose fields with a name attribute will be read.
  • submitter

    optional, button

    The button that submitted the form. If it has name and value attributes, its value is included in the data too.

More examples

#
Handling a form submission
JavaScript
const form = document.querySelector('#feedback')

form.addEventListener('submit', (event) => {
  event.preventDefault()
  const data = new FormData(form, event.submitter)
  console.log([...data])
})

form.querySelector('button').click()
Console
[['message', 'Great course!'], ['rating', '5'], ['action', 'send']]

From a group of radio buttons, only the checked value is included. The submit button is in the data because we passed event.submitter as the constructor’s second argument.

Several values under the same name
JavaScript
const data = new FormData(document.querySelector('#topics'))

console.log(data.get('topic'))
console.log(data.getAll('topic'))
console.log(Object.fromEntries(data))
Console
dom
['dom', 'api']
{ topic: 'api' }

get() returns only the first value, and Object.fromEntries() keeps the last one. Only getAll() gives every checked topic.

Sending a file with fetch()
JavaScript
const form = document.querySelector('#avatar-form')

form.addEventListener('submit', async (event) => {
  event.preventDefault()
  const data = new FormData(form)
  data.append('userId', '42')

  const response = await fetch('/api/avatar', { method: 'POST', body: data })
  console.log(await response.json())
})
Result
{ url: '/avatars/42.webp' }

This example needs a server, so it doesn’t run in the preview, and the result is a sample API response. The file from the <input type="file" name="avatar"> field is included in the data automatically, and the browser sets the Content-Type header itself.

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • Give every field a name attribute. Fields without one never make it into FormData, even if they have a value.
  • When sending FormData through fetch(), don’t set the Content-Type header. The browser adds it itself, along with the boundary that separates the fields.
  • For several checkboxes with the same name, use getAll(). get() only returns the first checked value.

Related entries

#

Spotted a mistake or missing an example? Write to us.