Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Frontend Basics for Backend Developers  ›  Capstone Project

JavaScript — the Client You Don't Control

JavaScript 14 minBrowser JavaScript calls your API with fetch and JSON, but anyone can change it or bypass it, so the server must validate every request and compute anything that matters itself.

JavaScript — the Client You Don't Control

Modern pages rarely reload to talk to the server. The bookshop's "Add to basket" button runs JavaScript that sends a small JSON request to your API and updates the page in place. That code runs on the shopper's machine, where the shopper can read it, change it or skip it entirely.

The rule

Every request is a suggestion; the server decides what is true.

The browser's fetch function sends HTTP requests from JavaScript:

const res = await fetch("/api/books?limit=5");
if (!res.ok) {
  throw new Error(`Request failed: ${res.status}`);
}
const books = await res.json();

Two details matter to a backend developer:

  • fetch does not reject on 4xx or 5xx. It only rejects when there is no response at all, such as a network failure. A 404 or 500 still resolves, with res.ok set to false. That is why your status codes must be honest: the client's error handling depends on them.
  • JSON bodies need a header. When sending JSON, the client should say so, and your server should read the body as JSON:
await fetch("/api/orders", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ book_id: 42, quantity: 1 }),
});

Now the key point. Anyone can open the browser's developer tools and change this code, or skip the page and send the request with a tool such as curl:

curl -X POST https://bookshop.example/api/orders \
  -H "Content-Type: application/json" \
  -d '{"book_id": 42, "quantity": -5, "price": 1}'

The server cannot tell whether a request came from your page or from someone typing. So treat every field as untrusted input.

The shortcut

For each field in a request body, ask: "What if someone typed any value here by hand?" If a wrong value could cost money, leak data or break things, the server must check it or compute it itself.

Handling POST /api/orders safelyStep 1 of 4
  1. List the fields

    The page sends book_id, quantity and, unwisely, price.

This is also why the server's error responses should be clear and specific. The page can show "Only 3 copies left" straight from the server, instead of copying every rule into JavaScript and hoping the two copies never drift apart.

Drills

Answer fast — trust the rule.

quick drill

A fetch call gets a 500 response. What happens?

quick drill

The checkout sends {"book_id": 42, "quantity": 1, "price": 1}. What should the server do with price?

quick drill

Which header tells the server that a request body is JSON?

quick drill

The page's JavaScript already rejects negative quantities. Should the server check again?

Remember

  • Every request is a suggestion; the server decides what is true.
  • For each field, ask "what if someone typed this by hand?", then validate it or compute it on the server.
  • fetch resolves on 4xx and 5xx; honest status codes make the client's res.ok meaningful.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainThe one-rupee book

The checkout page sends {"book_id": 42, "quantity": 1, "price": 399} to POST /api/orders. Someone edits the request and sends a price of 1. Explain what goes wrong if the server trusts the body, how it should handle the order instead, and whether the page's own JavaScript checks are still worth having.