JavaScript and forms
Submit a form with fetch
Send FormData or JSON with fetch, inspect the HTTP status, and update the interface only after the server confirms the result.
8 minute lesson
Use fetch() when you want to submit in the background and update the current page.
Start from a working native form, then enhance its submit event:
form.addEventListener('submit', async event => {
event.preventDefault()
const data = event.submitter
? new FormData(form, event.submitter)
: new FormData(form)
const response = await fetch(form.action, {
method: form.method,
body: data,
headers: {
Accept: 'application/json'
}
})
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
const result = await response.json()
console.log(result)
})
fetch() resolves when it receives an HTTP response, even when the status is 400 or 500. Check response.ok or response.status before treating the operation as successful.
The response format is part of the endpoint contract. If the client asks for JSON, the server should return JSON for both success and expected validation failures. Do not call response.json() on an HTML error page and hide the resulting parse error from the user.
Network failures reject the promise. Handle them separately from validation errors because the person may need to retry without changing any fields.
While the request is pending, disable the relevant submitter and show a clear status. Restore it in a finally block so an error does not leave the form stuck.
The server must still validate, authorize, and protect against duplicates. fetch() changes the interface, not the trust boundary.
Test one success, one validation response, one server error, and offline mode in DevTools.
Lesson completed