Posting form-style data
$.post(url, data, callback) sends a POST request. By default the data is encoded the same way a normal HTML form encodes it (application/x-www-form-urlencoded), which every server framework understands:
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$.post("https://jsonplaceholder.typicode.com/posts", { title: "My first post", body: "Hello", userId: 1 })
.done(function (created) {
console.log("created with id", created.id);
console.log("title:", created.title, "| userId:", created.userId);
});
</script>created with id 101
title: My first post | userId: 1JSONPlaceholder pretends to save the post and returns it with a new id of 101. It does not really store anything, so the same request always gives the same answer, which makes it good for learning.
Sending a whole form
.serialize() reads every field in a form and builds that encoded string for you:
<form id="comment-form">
<input name="name" value="Asha Verma">
<input name="email" value="asha@example.com">
<textarea name="body">Great lesson & clear examples</textarea>
<label><input type="checkbox" name="subscribe" value="yes" checked> Subscribe</label>
<input name="secret" value="x" disabled>
<button>Post comment</button>
</form>
<p id="status"></p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#comment-form").on("submit", function (event) {
event.preventDefault();
const payload = $(this).serialize();
console.log("sending:", payload);
$.post("https://jsonplaceholder.typicode.com/comments", payload)
.done(function (saved) {
$("#status").text("Thanks, " + saved.name + "! Comment #" + saved.id + " posted.");
console.log("saved id:", saved.id, "| subscribe:", saved.subscribe);
});
});
</script>sending: name=Asha%20Verma&email=asha%40example.com&body=Great%20lesson%20%26%20clear%20examples&subscribe=yes
saved id: 501 | subscribe: yes.serialize() follows the same rules as a real form submission: only fields with a name, not disabled, and only ticked checkboxes and radios. The & in the comment was encoded as %26 so it cannot break the format. .serializeArray() gives the same fields as an array of { name, value } objects if you need to inspect or change them first.
Sending JSON
Many modern APIs expect a JSON body instead. Set contentType to say what you are sending, and convert the data to a JSON string yourself:
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const order = { customer: "Ravi", items: [{ sku: "LAMP-1", qty: 2 }], gift: false };
$.ajax({
url: "https://jsonplaceholder.typicode.com/posts",
method: "POST",
contentType: "application/json",
data: JSON.stringify(order),
dataType: "json"
}).done(function (saved) {
console.log("id:", saved.id, "| items:", saved.items.length, "| first sku:", saved.items[0].sku, "| gift:", saved.gift);
});
</script>id: 101 | items: 1 | first sku: LAMP-1 | gift: falseNotice the three settings working together:
contentType: "application/json"describes the request body;data: JSON.stringify(order)is that body, as a string (withoutstringify, jQuery would form-encode the object);dataType: "json"describes the response.
JSON keeps types and nesting: the server received gift as a real false and items as an array, which form encoding cannot express directly.
PUT, PATCH and DELETE
REST APIs use different methods for different actions: PUT replaces a resource, PATCH changes part of it, DELETE removes it. Set method in $.ajax():
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const base = "https://jsonplaceholder.typicode.com/posts/1";
$.ajax({ url: base, method: "PATCH", contentType: "application/json", data: JSON.stringify({ title: "Updated title" }) })
.then(function (post) {
console.log("PATCH:", post.id, post.title);
return $.ajax({ url: base, method: "DELETE" });
})
.then(function (result, status, xhr) {
console.log("DELETE status:", xhr.status, "| body:", JSON.stringify(result));
});
</script>PATCH: 1 Updated title
DELETE status: 200 | body: {}Returning the second request from the first .then() makes them run one after the other: the delete starts only after the update has finished. The Deferreds lesson explains this chaining.
Uploading files
.serialize() cannot include files. Use the browser's FormData object, and tell jQuery not to process it:
$("#avatar-form").on("submit", function (event) {
event.preventDefault();
const formData = new FormData(this); // includes <input type="file"> fields
$.ajax({
url: "/profile/avatar",
method: "POST",
data: formData,
processData: false, // do not turn FormData into a string
contentType: false // let the browser set multipart/form-data with its boundary
}).done(() => console.log("uploaded"));
});Both options matter. Without processData: false, jQuery tries to convert the object; without contentType: false, it sends the wrong header and the server cannot read the file.
Protect your write requests
Requests that change data should be protected against CSRF (cross-site request forgery). Frameworks such as Laravel give each page a token; send it with every POST, PUT, PATCH and DELETE, usually as a header set once with $.ajaxSetup() (previous lesson). And validate every value again on the server, exactly as you would for a normal form.
Common mistakes
- Passing an object as
datawhen the API expects JSON, which sends form encoding. - Using
dataType: "json"to send JSON. It describes the response. - Serialising a form whose fields have no
name: they are skipped silently. - Forgetting
processData: falseandcontentType: falsefor file uploads. - Sending write requests without CSRF protection.
Exercise
Build a small form with title and body fields. On submit, send it as JSON to https://jsonplaceholder.typicode.com/posts and log the id and title that come back.
Show one possible answer
<form id="f"><input name="title" value="Hello"><input name="body" value="World"><button>Send</button></form>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#f").on("submit", function (event) {
event.preventDefault();
const data = {};
$.each($(this).serializeArray(), (i, field) => { data[field.name] = field.value; });
$.ajax({
url: "https://jsonplaceholder.typicode.com/posts",
method: "POST",
contentType: "application/json",
data: JSON.stringify(data),
dataType: "json"
}).done(saved => console.log(saved.id, saved.title));
});
</script>101 HelloKey points
- $.post(url, data) sends data form-encoded, the same format as a normal HTML form.
- $(form).serialize() turns every named field into that format, ready to post.
- To send JSON, set contentType: "application/json" and pass JSON.stringify(data).
- Files need FormData with processData: false and contentType: false.