$.post() is jQuery’s readable POST shorthand. This tutorial covers both official signatures, how it maps to $.ajax(), sending data in the request body, the success callback arguments, parsing JSON with the fourth dataType argument, form submission with .serialize(), chaining .done(), .fail(), and .always() on the returned jqXHR, the settings-object form since jQuery 1.12, never-cached POST behavior, and when to upgrade to full $.ajax().
01
POST Shorthand
$.post(url, ...)
02
Body Data
Request payload
03
success
Callback args
04
Forms
.serialize()
05
jqXHR
done/fail/always
06
settings
Since jQuery 1.12
Fundamentals
Introduction
Creating a comment, saving a profile, submitting a contact form — these operations send data to the server, not just read from it. jQuery makes that one line with $.post(). Pass a URL and a data object; jQuery sends an asynchronous HTTP POST request with the payload in the request body and invokes your callback when the server responds successfully.
Under the hood, $.post() is not a separate transport — it is a thin wrapper around jQuery.ajax() with type: "POST" preset. That means you inherit the same jqXHR return value, global Ajax events on document, and Promise-style chaining. POST requests are never cached, so every call hits the server fresh. When your needs outgrow a one-liner — JSON bodies, custom headers, or global: false — you drop down to $.ajax() without changing mental models.
Concept
Understanding jQuery.post()
jQuery.post() sends data to a server using an HTTP POST request. The method returns immediately with a jqXHR object while the network call runs in the background. If you pass a success function, jQuery calls it with the response body once parsing completes — the exact type depends on the optional dataType argument or jQuery’s intelligent guess from the Content-Type header.
The optional data argument is a plain object, string, or serialized form string sent in the request body — ideal for form fields, create/update payloads, and search terms you do not want visible in the URL. Unlike GET query parameters, POST body data is not bookmarkable and should be used for writes and sensitive input.
💡
Beginner Tip
Always chain .fail() on the jqXHR returned by $.post(). Like $.get(), a bare POST fails silently on HTTP errors — users see nothing unless you handle failures. For Ajax form submission, call event.preventDefault() and POST with $.post(url, $form.serialize()) instead of a full page reload.
The classic form — URL first, optional body data, optional success callback, optional expected response type. When providing dataType without data, pass null or undefined as the second argument (required in jQuery 3.x).
Four ways to move data — pick the shortest readable form or the API with the control you need.
$.post()
POST shorthand
$.post(url, data, success) — one-liner for writes; data in request body; never cached
$.get()
GET shorthand
$.get(url, data, success) — same positional pattern for reads; data appended to URL
$.ajax()
full control
Every setting exposed — headers, contentType, beforeSend, processData, global:false
fetch()
native API
fetch(url, { method: "POST", body }) — no jQuery; does not trigger global Ajax events
Use $.post() for simple form submissions and creates. Use $.get() for reads. Use $.ajax() when you need JSON bodies, custom headers, or global: false. Use fetch() in vanilla JS projects without jQuery.
Hands-On
Examples Gallery
Five progressive examples from a basic POST with body data through JSON responses, serialized form submission, Ajax form handling with preventDefault, and jqXHR chaining. Each links to a Try-it lab where you can edit and run the code in the browser.
📚 Core Patterns
Send data to the server with the positional $.post() signature.
Example 1 — POST with data object and success callback
Adapted from the official docs: send { name, time } and display the server response.
Click #save → POST /posts with title, body, userId in request body
JSONPlaceholder returns created object with id → #result shows "Created post #101"
HTTP 201 Created (or 200) — success callback runs with parsed JSON
How It Works
The second argument is serialized with $.param() and sent as the POST body. The third argument is the success callback — jQuery invokes it with (data, textStatus, jqXHR) when the server returns a success status. Data stays out of the URL.
Example 2 — Fourth argument dataType: "json"
Official pattern: POST with a payload and explicitly expect a JSON response.
POST with dataType "json" → body parsed before callback
#json-out shows "id=101, title=Hello"
typeof data in callback is "object" — not a raw string
How It Works
When you pass "json" as the fourth argument, jQuery parses the response body into a JavaScript object before your callback runs. Invalid JSON triggers the error path on the jqXHR — chain .fail() to handle it.
Example 3 — POST serialized form data
Official docs pattern: pass $("#form").serialize() as the data argument.
jQuery
$( "#submit-form" ).on( "click", function() {
var payload = $( "#contact-form" ).serialize();
// e.g. "name=John&email=john%40example.com&message=Hello"
$.post(
"https://jsonplaceholder.typicode.com/posts",
payload,
function( data ) {
$( "#status" ).text( "Saved! Server assigned id " + data.id );
},
"json"
);
} );
serialize() reads named form fields → URL-encoded string
$.post sends string as POST body (already encoded)
#status shows "Saved! Server assigned id 101"
How It Works
.serialize() returns a pre-encoded query string from form inputs with name attributes. Pass it directly as data — jQuery does not re-serialize strings. Map field names to what your API expects, or use a plain object if you need bracket notation for arrays.
📈 Ajax Forms & jqXHR
Submit forms without page reload and chain Promise-style handlers.
Example 4 — Ajax form submit with preventDefault
Adapted from the official jQuery.post demo: intercept form submit, POST via Ajax, inject HTML response.
jQuery
$( "#searchForm" ).on( "submit", function( event ) {
event.preventDefault();
var $form = $( this ),
term = $form.find( "input[name='s']" ).val(),
url = $form.attr( "action" );
var posting = $.post( url, { s: term } );
posting.done( function( data ) {
$( "#result" ).empty().append(
"<p>Search sent: <strong>" + term + "</strong></p>" +
"<pre>" + JSON.stringify( data, null, 2 ) + "</pre>"
);
} );
} );
User submits form → preventDefault stops page reload
$.post sends { s: term } in body → .done() updates #result in place
Page stays on same URL — no full navigation
How It Works
Store the jqXHR in posting so you can chain handlers or call .abort() if the user submits again before the first request finishes. This is the foundation of single-page-style form handling in jQuery apps.
Success → #log shows done + always entries; #spinner hidden
Server error → fail + always run; done skipped
Second .always() attached later still fires (or immediately if done)
How It Works
Since jQuery 1.5, all Ajax methods return a Promise-like jqXHR. Prefer .done() / .fail() / .always() over deprecated jqXHR .success() / .error() / .complete() removed in jQuery 3.0.
Applications
🚀 Common Use Cases
Form submission — POST contact, login, or signup forms without a full page reload.
Create records — send new blog posts, comments, or cart items to a REST API.
Inline edits — save a field when the user blurs an input or clicks Save.
Vote / like buttons — POST a user action and update the UI from the JSON response.
Search with POST — send large or sensitive filter payloads in the body instead of the URL.
Delete confirmations — POST or use full $.ajax({ method: "DELETE" }) after user confirms.
🧠 How $.post() Works Internally
1
Expand to $.ajax()
$.post() maps positional args to { url, data, success, dataType, type: "POST" } and delegates to jQuery.ajax().
$.ajax()
2
Return jqXHR immediately
Caller receives a jqXHR object right away — attach .done() / .fail() before or after the response arrives.
jqXHR
3
Serialize body data
Plain objects pass through $.param() into application/x-www-form-urlencoded body text. Strings and serialized forms pass through as-is.
$.param()
4
Send POST (never cached)
XHR sends POST with body payload. Browser and jQuery do not cache POST responses — cache and ifModified have no effect.
POST
5
Parse & success + .done()
Response parsed per dataType or Content-Type. Legacy success callback and chained .done() handlers run with (data, textStatus, jqXHR).
.done()
6
👉
Error path or ajaxComplete
HTTP errors and network failures invoke .fail(). Global ajaxComplete fires either way. Chain .fail() — POST fails silently by default.
Important
📝 Notes
$.post() is asynchronous — code after the call runs before the server responds.
It is shorthand for $.ajax() with type: "POST" — same jqXHR, same global Ajax events.
Never cached: POST requests always hit the server; cache and ifModified in ajaxSetup are ignored.
Body encoding: plain objects serialize via $.param(); pass a string from .serialize() for pre-encoded form data.
JSON APIs: for application/json bodies use $.ajax({ contentType: "application/json", data: JSON.stringify(obj) }) — $.post() defaults to form encoding.
Prefer .done() / .fail() / .always() over deprecated jqXHR methods removed in jQuery 3.0.
Same-origin: most Ajax POST requests require CORS headers for cross-domain URLs.
When providing dataType without data, pass null as the second argument in jQuery 3.x.
Compatibility
Browser Support
jQuery.post() is part of jQuery’s core Ajax module — not a native DOM API. It works wherever jQuery’s Ajax transport runs: all browsers supported by your jQuery version, including legacy IE with supported jQuery builds.
✓ jQuery 1.0+
jQuery.post() method
Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. jqXHR promise methods (.done, .fail, .always) arrived in jQuery 1.5. Settings-object signature since jQuery 1.12. Deprecated jqXHR .success/.error/.complete removed in jQuery 3.0.
100%With jQuery
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
$.post()Universal
Bottom line: Safe in any jQuery project. Use $.post() for simple form-encoded writes; $.ajax() for JSON bodies or custom headers; fetch() is the native alternative when jQuery is not loaded.
Wrap Up
Conclusion
jQuery.post() is the fastest path from data object to server for write operations and form submissions. Learn the positional signature (url, data, success, dataType), chain .fail() so errors are not silent, and reach for $.ajax() when you need JSON bodies or custom headers.
Chain .fail() on every $.post() so users see submission errors
Use event.preventDefault() when converting forms to Ajax POST
Set dataType: "json" explicitly when you expect JSON from the server
Return jqXHR from helper functions so callers can chain or abort
Upgrade to $.ajax() for JSON bodies, file uploads, or global: false
❌ Don’t
Assume errors surface automatically — $.post() fails silently by default
Use POST for idempotent reads that could be GET — wastes server resources
Send passwords over HTTP — always POST sensitive data over HTTPS
Use deprecated jqXHR .success() / .error() / .complete() in jQuery 3.x
Double-submit forms — disable the button or abort the previous jqXHR while a POST is in flight
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about $.post()
Data in body, jqXHR out, chain fail().
6
Core concepts
post01
POST Shorthand
$.post(url, ...)
Write
body02
Body Data
Not in URL
Payload
cb03
success
data, status, jqXHR
Callback
fm04
Forms
.serialize()
Submit
xhr05
jqXHR
done/fail/always
Promise
nc06
Never Cached
Fresh each call
POST
❓ Frequently Asked Questions
jQuery.post() is a shorthand for $.ajax() configured as a POST request. Pass a URL, optional data object or string, optional success callback, and optional dataType — jQuery sends the request asynchronously with data in the request body and returns a jqXHR object. Since jQuery 1.12 you can also pass a single settings object: $.post({ url, data, dataType }). It is the readable one-liner most developers reach for when submitting forms or creating records.
Both share the same positional signature (url, data, success, dataType), but $.post() sets type to POST so data goes in the request body as application/x-www-form-urlencoded by default, while $.get() appends data to the URL as query parameters. Use $.get() for reads and $.post() for writes, form submissions, and any operation that should not expose payload data in the URL.
It returns a jqXHR object — a superset of XMLHttpRequest that implements jQuery's Promise interface. Chain .done(fn) for success, .fail(fn) for errors, and .always(fn) for either outcome. Handlers can be attached after completion; if the request already finished, the callback fires immediately. Call jqXHR.abort() to cancel an in-flight POST.
No — pages fetched with POST are never cached. The cache and ifModified options in jQuery.ajaxSetup() have no effect on $.post() requests. Each POST is sent fresh to the server.
Yes — if the server returns an error status or the request fails, $.post() does not alert you unless you chain .fail() on the returned jqXHR, register a global ajaxError handler on document, or handle errors another way. The success callback simply never runs. Always chain .fail() when users need feedback on failure.
Use $.post() for simple POST requests with minimal options. Use $.ajax() when you need full control: custom headers, contentType application/json, beforeSend, processData false for FormData, global false, or other settings $.post() does not expose as positional arguments.
Did you know?
$.post() has existed since jQuery 1.0 — the same release as $.get() and $.getJSON(). The jqXHR return value with Promise methods arrived in jQuery 1.5. The settings-object signature $.post({ url }) came in jQuery 1.12. POST requests are never cached by jQuery — unlike GET, the cache option in ajaxSetup has zero effect on $.post() calls. Under the hood, every call routes through jQuery.ajax(), which is why global ajaxStart and ajaxStop fire unless you use global: false in the settings form.