How the web works
The idea
Every time you open a website, an invisible conversation happens in less than a second. Think of a busy restaurant. You sit at a table and place an order. A kitchen you never see reads it, cooks, and sends a plate back to you.
The web works the same way. Your browser places orders, computers somewhere else prepare the answers, and the browser lays the result on your screen. This lesson walks through that whole trip, and then shows you how to watch it happen live in your own browser.
You only need a browser (Chrome, Edge or Firefox all work, and every tool in this lesson exists in all three) and the terminal you already know. Nothing here is graded. You will look, click and poke, and every later lesson depends on what you see.
Clients and servers
In the restaurant picture, you are the client: the one who asks. Your browser is a client. So is a phone app that loads your messages. A client always speaks first, and it always asks for something specific.
The kitchen is the server: the one who answers. A server is not a special kind of machine. It is a program that stays running, waits for orders, and answers each one. It usually runs on a computer in a data center that is always switched on and connected.
Three facts follow from this picture:
- One kitchen serves thousands of tables at once.
- The client asks, the server replies, and then the conversation is over. The server cannot start talking to you on its own. (Clever tricks for this exist, and a later lesson covers them.)
- "Client" and "server" are jobs, not kinds of computers. Later in this course your own laptop will play both jobs at once: it will run a server and a browser that talks to it.
Look at the conversation yourself. Open example.com in your browser, a tiny page built for demonstrations. Then open your browser's developer tools (the next-but-two section explains them, but try it now): press F12 on Windows and Linux, or Cmd+Option+I on a Mac, and click the Network tab. Reload the page. You will see a table like this:
Name Status Type Size
example.com 200 document 1.2 kB
Your panel may show a few more rows. Each row is one order your browser placed. The row named example.com is the order for the page itself, and the numbers are the kitchen's reply.
URLs, DNS and IP addresses
To place an order, the client has to know who to ask and what to ask for. Picture your phone. You call a person by name, and the phone turns the name into a number. After the person picks up, you can ask for a particular extension.
A URL is the full phone instruction for one page. Take this one:
https://example.com/docs/intro.html
Read it in three parts:
httpsis how to talk. It is the scheme. Thesstands for secure: the conversation is scrambled while it travels, so strangers watching the line cannot read it.example.comis the host: the name of who to call./docs/intro.htmlis the path: the extension to ask for, which says which page you want from that host. It reads just like the paths you typed in the terminal.
Computers do not call each other by name. They call by number. That number is an IP address, a label such as 93.184.216.34 that identifies one machine on the internet. (Some are longer and contain letters, like 2606:2800:220:1:248:1893:25c8:1946. They are the newer kind and work the same way.)
So something has to turn the name into the number, like the contacts list on your phone. That service is DNS (the Domain Name System). Before your browser places any order, it quietly asks DNS "what is the number for example.com?" and gets back an IP address. You never see this step, but you can watch its result with ping, a command that sends one tiny hello to a computer and times the reply. The -c 1 flag means "count: send just one":
ping -c 1 example.com
PING example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=12.3 ms
--- example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
Your numbers will differ, and on macOS the wording differs a little. The key piece is the first line: ping looked up example.com in DNS and printed the IP address it got back in parentheses. If your network blocks pings, you will see 100% packet loss, but that first line still shows the number DNS found.
HTTP requests, responses and status codes
Now the conversation itself. HTTP is the set of rules for how orders and replies are written, so that every browser and every server understand each other. An order is a request. The reply is a response.
Here is a simplified request, the order your browser sends for the page at the top of example.com:
GET / HTTP/1.1
Host: example.com
Read it left to right. GET is the kind of order: "please hand me this". / is the path, which here means the front page. HTTP/1.1 is the version of the rules. The Host line names which restaurant the order is for, because one building can hold many kitchens.
And a simplified response:
HTTP/1.1 200 OK
Content-Type: text/html
<h1>Example Domain</h1>
The first line holds the status code, a three-digit number that is the waiter's reply, plus a short label. 200 OK means "here is your order". Below it, Content-Type says what kind of food is on the plate (text/html is a web page). After the blank line comes the plate itself, called the body.
The first digit of a status code tells you who to look at:
2xxmeans success.200 OKis the usual one.3xxmeans "we moved".301says "go to this other address instead", and your browser follows it automatically.4xxmeans "your order was wrong".404 Not Foundis the famous one: there is no such dish on the menu.5xxmeans "the kitchen has a problem".500 Internal Server Erroris the kitchen on fire. It is not your fault.
You will see these numbers in the next sections, and the Try it steps ask you to cause a 404 on purpose.
HTML, CSS and JavaScript: who does what
When the plate arrives, the browser needs to turn it into something you can see and click. Three languages share that job, and each has one role.
- HTML says what is on the page. It builds a tree of labeled boxes: a heading box, a paragraph box, and so on.
- CSS says how it looks: colors, sizes and spacing.
- JavaScript says what it does: it changes the boxes after the page has loaded, and it reacts when you click.
Make a tiny page with all three. Create a folder and a file:
mkdir -p ~/web-basics
cd ~/web-basics
code three-parts.html
Type this into the file and save it:
<h1 id="title">Hello</h1>
<p>This page has three parts.</p>
<style>
h1 { color: tomato; }
</style>
<script>
document.getElementById("title").textContent = "Hello, web";
</script>
Here is who does what. The first two lines are HTML: h1 is a tag for a big heading, p is a tag for a paragraph, and id="title" is a name tag so other parts can point at that box. The <style> block is CSS, and its one rule says "make every heading tomato red". The <script> block is JavaScript, and its one line says "find the box named title and swap its words for new ones". The exact spelling of each piece is a later topic. For now, only notice the three jobs.
Open the page in your browser. On macOS run open three-parts.html. On Linux run xdg-open three-parts.html. On Windows, from the Ubuntu window, run explorer.exe . to open the folder and double-click the file.
You should see a tomato-red heading that says Hello, web, not Hello. The words in the file said Hello, so the proof of JavaScript is that the words on screen differ from the words you typed.
The browser's developer tools
Every browser has a backstage pass. It lets you see how the stage was set, which deliveries arrived through the back door, and what the stage manager is saying. These are the developer tools, and you will use them for the rest of your career.
Open them with F12, or Ctrl+Shift+I on Windows and Linux, or Cmd+Option+I on a Mac. You can also right-click any part of a page and choose Inspect. Three tabs matter first. (Firefox calls the first one Inspector.)
Elements shows the live tree of boxes, built from the HTML after JavaScript has finished changing it. On your three-parts.html page the heading shows Hello, web, even though the file says Hello. Double-click the heading's text in this panel, type something else, and the page changes immediately. Reload the page and your change disappears. You only edited your own browser's copy. The real file and everyone else's screen are untouched, which makes it a safe place to experiment.
Network is the delivery log from earlier. Every order your browser places while the tools are open appears as a row. Click a row to see more. The Headers tab shows the extra notes that travel with each order and reply. The Preview or Response tab shows the body. A red row usually means a 4xx or 5xx status.
Console is the stage manager's message board. Errors from the page appear here in red, and it also has a prompt where you can type a line of JavaScript and see the answer straight away:
2 + 2
4
document.title
'Hello'
document is how JavaScript refers to the current page, and title is the text shown in the browser tab. When you type a name that does not exist, the Console reports it like this:
nonsense
Uncaught ReferenceError: nonsense is not defined
Read it piece by piece: Uncaught means nothing handled the problem, ReferenceError is the kind of problem (a name was used that was never created), and nonsense is not defined names the culprit.
Static sites, web apps and APIs
Not every server does the same job. Back at the restaurant, there are three ways to run the kitchen.
A static site is a printed menu. The files are written ahead of time, and the server simply hands the same pages to everyone. A site like example.com, a personal portfolio, or a document page is static. It is fast, cheap and hard to break.
A web app cooks to order. The pages you see depend on who you are and what you did: your inbox, your cart, your dashboard. The server works out each page for you, and JavaScript in your browser keeps updating the page while you use it. Open the same GitHub address while signed in and again in a private window, and you will get two different pages from one URL.
An API is the pickup window where the kitchen hands out raw ingredients instead of a finished plate. There is no layout and no color, just labeled data that another program can use. Websites and apps call APIs behind the scenes to fill their pages. You can look at a real one by opening this address in your browser:
https://api.github.com/users/octocat
You will see plain text that starts like this (shortened here):
{
"login": "octocat",
"id": 583231,
"type": "User",
"name": "The Octocat"
}
Every line is a label and a value. No page design is involved, because the reader is meant to be a program, not a person. Full-stack development means building both halves: the pages people see, and the servers and APIs that feed them.
Common mistakes
- Opening the developer tools after the page loaded. The Network tab only records orders placed while it is open. Open it first, then reload.
- Thinking your edits in the Elements tab are saved. They live only in your browser's copy and vanish on reload. Make permanent changes in your files.
- Mixing up who is to blame for a status code.
4xxmeans the request was wrong or the page does not exist.5xxmeans the server broke. - Seeing an old page after you changed a file. Browsers keep copies to go faster. Reload without the saved copy with
Ctrl+Shift+R(orCmd+Shift+Ron a Mac). - Typing
http://where the site needshttps://. Most sites forward you to the secure version, but not all, and the plain one does not scramble the conversation. - Pasting code someone gave you into the Console. The Console can do anything you can do on that page. Never paste something you do not understand, especially from a stranger who says it will "unlock" something.
- Assuming a page that looks professional is safe. Looks come from CSS, and anyone can copy them. Check the host name in the address bar.
Try it
- Watch a client and a server talk. Open example.com in your browser, open the developer tools with
F12(orCmd+Option+Ion a Mac), click the Network tab, and reload the page. Find the row namedexample.com. You should see a status of200. Click that row and open its Headers tab. Find the line that shows the request's address and the line that shows the remote address (an IP address followed by a number). - Look up a name. In your terminal run
ping -c 1 example.com. Compare the IP address in the first line with the remote address you saw in step 1. They should usually match, though big sites sometimes answer from several addresses. Then take the addresshttps://example.com/docs/intro.htmland say aloud which part is the scheme, the host and the path. - Cause a 404 on purpose. With the Network tab still open, visit
https://gonomicon.com/nothing-here. Find the row for the page. You should see a status of404(usually shown in red). Say in one sentence whether this was the client's fault or the server's fault. - Build the three-part page. Follow the steps in the HTML, CSS and JavaScript section to create
~/web-basics/three-parts.htmland open it in your browser. You should see a tomato-red heading that saysHello, web. Back in VS Code, delete the whole<script>block, save, and reload: the heading now saysHello. Put the script back, then delete the<style>block, save, and reload: the heading is plain black. Note which part controls the words, and which part controls the color. - Edit a page live. On the same page open the Elements tab (or Inspector in Firefox). Double-click the heading's text and type
I was here. The page updates. Reload and watch your change disappear. Write down why the real file did not change. - Use the Console. Open the Console tab and type
2 + 2, then press Enter: it should print4. Typedocument.titleand you should see the page's title. Typenonsenseand read the red error out loud, piece by piece. - Compare a static site, a web app and an API. Open example.com and note that it looks the same for anyone. Open github.com in a normal window while signed in, then open the same address in a private window and note that the page differs. Finally open
https://api.github.com/users/octocatand note that it shows labeled data instead of a designed page. In the Network tab, check that each of these loaded with a200status.