jQuery Submit Form — Legacy Codebase Reference
Submit a form with jQuery `$.ajax` — for legacy codebases that already require jQuery. Same mechanics as vanilla JS fetch, different syntax. For new projects, prefer fetch.
If your codebase already includes jQuery, `$.ajax` is the natural way to submit forms. Same mechanics as vanilla fetch — intercept submit, POST, update UI based on response — but with jQuery's chained-Promise syntax (`.done()`, `.fail()`, `.always()`) instead of async/await.
The critical bits for FormData submission with jQuery are `processData: false` (don't let jQuery URL-encode the FormData object — let the browser handle the multipart encoding) and `contentType: false` (don't let jQuery set the Content-Type header — the browser sets it with the correct boundary string for multipart/form-data). Miss either and the upload fails silently.
`.done()` fires on HTTP 2xx; `.fail()` fires on network errors and HTTP 4xx/5xx; `.always()` runs after either. Use `.always()` to re-enable the submit button regardless of outcome — same pattern as vanilla JS's `finally` block.
For new projects in 2026, prefer fetch over $.ajax. Same capabilities, no 90KB jQuery dependency, native browser API. Only use $.ajax if your codebase already pulls jQuery for other reasons.
How to set this up
Include jQuery from CDN
One <script> tag. ~30KB minified. Skip this in new projects.
$(form).on('submit', handler)
Attach a submit handler. e.preventDefault() blocks native submission.
$.ajax with processData/contentType: false
Required for FormData uploads. Browser sets Content-Type with the correct boundary.
Use .done/.fail/.always for state
Chained Promise-like callbacks. .always() runs regardless of outcome — re-enable submit there.
Legacy codebases only. New projects use fetch.
Frequently asked questions
How do I submit a form with jQuery?
Attach a submit handler with $(form).on('submit', fn). Inside, call e.preventDefault() and use $.ajax to POST the form. Same pattern as vanilla fetch, different syntax.
What's processData: false and contentType: false in jQuery $.ajax?
processData: false tells jQuery not to URL-encode the FormData object — let the browser handle multipart encoding. contentType: false tells jQuery not to set the Content-Type header — let the browser set it with the correct boundary string. Both are required for FormData uploads.
Should I use jQuery for form submission in 2026?
Only if your codebase already requires jQuery. For new projects, vanilla fetch is the modern default — same capabilities, no 90KB dependency.
How do I handle errors in jQuery $.ajax?
Use .fail() for network errors and HTTP 4xx/5xx. .always() runs regardless of outcome — re-enable the submit button there. .done() fires only on HTTP 2xx.
Related guides
Ship the form, not the backend.
Free for 1,000 submissions/month. Email delivery, AI spam filtering, signed webhooks, real dashboard — all on the free plan. No credit card.
Get a free access key →