Skip to main content

Module 16: The Server-Side Era

How the web began — static pages, CGI scripts, and the rise of PHP (1991–2005)


Learning Objectives

By the end of this module, you will:

  • Understand the original architecture of the web
  • Know why CGI was revolutionary (and limited)
  • See how PHP dominated web development
  • Recognize server-side patterns still used today
  • Appreciate why the "page refresh" era had to end

Time: 1-2 hours (reading)


Introduction

Before React. Before JavaScript frameworks. Before AJAX. There was... a page refresh.

Every interaction required:

  1. Click a link or submit a form
  2. Browser sends request to server
  3. Server generates entire HTML page
  4. Browser loads completely new page

This seems primitive now. But it was revolutionary in 1991.


Part 1: The Original Web (1991-1993)

Tim Berners-Lee's Vision

The web started as a document sharing system at CERN. The original components:

  • HTML — Markup language for documents
  • HTTP — Protocol for requesting documents
  • URLs — Addresses for documents
  • Web Server — Software that serves documents
  • Browser — Software that displays documents

That's it. No JavaScript. No CSS. No interactivity.

What "Web Page" Meant

<html>
<head>
<title>CERN Information</title>
</head>
<body>
<h1>Welcome to CERN</h1>
<p>This is a paragraph about physics.</p>
<p>Here is a <a href="other-page.html">link</a> to another document.</p>
</body>
</html>

Web servers were file servers. You requested page.html, and the server sent page.html. Simple.

The Request-Response Model

Browser                          Server
│ │
│ GET /index.html HTTP/1.0 │
│ ─────────────────────────────►│
│ │
│ HTTP/1.0 200 OK │
│ <html>...</html> │
│ ◄─────────────────────────────│
│ │
│ (User clicks link) │
│ │
│ GET /other.html HTTP/1.0 │
│ ─────────────────────────────►│
│ │

Every navigation = new request = full page load.


Part 2: Dynamic Pages with CGI (1993-1998)

The Problem

Static HTML was limiting. What if you wanted:

  • A page counter showing visits
  • A guestbook where users leave messages
  • Search results based on a query
  • Content from a database

You can't do this with static files.

The CGI Solution

CGI (Common Gateway Interface) let web servers run programs.

Instead of:

GET /page.html → Server sends file

You could:

GET /cgi-bin/counter.pl → Server runs program → Program outputs HTML

A CGI Program (Perl)

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<html><body>\n";
print "<h1>Page Views: 12,456</h1>\n";
print "</body></html>\n";

The program runs, outputs HTML to stdout, and the server sends that output to the browser.

CGI Architecture

┌─────────┐      ┌─────────┐      ┌──────────┐
│ Browser │ ───► │ Web │ ───► │ CGI │
│ │ ◄─── │ Server │ ◄─── │ Program │
└─────────┘ └─────────┘ └──────────┘
│ │
(passes request) (generates HTML)

CGI's Problems

  1. Performance: New process spawned for every request
  2. State: Each request independent (no sessions)
  3. Complexity: Managing HTML in print statements
  4. Security: Easy to create vulnerabilities

A busy site might spawn thousands of processes. Servers struggled.


Part 3: PHP Changes Everything (1995-2005)

The PHP Revolution

PHP (originally "Personal Home Page") solved CGI's problems:

  • Ran as a module inside the web server (no new process)
  • Mixed HTML and code naturally
  • Built-in features for forms, databases, sessions
  • Easy to learn for non-programmers

PHP Templating

Instead of printing HTML from code, embed code in HTML:

<html>
<body>
<h1>Welcome, <?php echo $username; ?>!</h1>

<?php if ($isLoggedIn): ?>
<p>You have <?php echo $messageCount; ?> new messages.</p>
<?php else: ?>
<p>Please <a href="login.php">log in</a>.</p>
<?php endif; ?>

<h2>Recent Posts</h2>
<?php foreach ($posts as $post): ?>
<div class="post">
<h3><?php echo $post['title']; ?></h3>
<p><?php echo $post['content']; ?></p>
</div>
<?php endforeach; ?>
</body>
</html>

The LAMP Stack

PHP's dominance was powered by LAMP:

  • Linux (operating system)
  • Apache (web server)
  • MySQL (database)
  • PHP (language)

Free, open-source, and available from every hosting provider. WordPress, Facebook, and Wikipedia all started on PHP.

Server-Side Rendering Pattern

Every page request:

1. Browser requests /posts.php
2. Apache receives request, invokes PHP
3. PHP:
- Connects to MySQL
- Queries for posts
- Loops through results
- Generates complete HTML
4. Apache sends HTML to browser
5. Browser renders page

The browser receives finished HTML. No JavaScript required.


Part 4: The Full Page Refresh Problem

What Users Experienced

Every interaction = white flash + wait:

Action              Result
─────────────────────────────────────────
Click "Add to Cart" → Full page reload
Submit comment → Full page reload
Click pagination → Full page reload
Change dropdown → Full page reload

Users in 2004 waited 2-5 seconds per page load. Interactions felt slow and disconnected.

The Architecture Limitation

The protocol was designed for documents:

┌──────────────────────────────────────────────────────────────┐
│ HTTP was designed for: │
│ │
│ "I want document X" → "Here is document X" │
│ │
│ NOT for: │
│ │
│ "Update this small part of the page" │
│ "Add this item without losing scroll position" │
│ "Show new comments without refreshing" │
└──────────────────────────────────────────────────────────────┘

Desktop Apps vs Web Apps

Desktop applications (Outlook, Word) had rich, responsive interfaces. Web applications felt primitive by comparison.

People asked: "Why can't the web work like a desktop app?"


Part 5: JavaScript's Early Days

JavaScript Arrives (1995)

Brendan Eich created JavaScript in 10 days at Netscape. Original purpose: small interactions without server round-trips.

// Early JavaScript (1995-2005)
function validateForm() {
if (document.forms[0].email.value == "") {
alert("Please enter your email!");
return false;
}
return true;
}

What JavaScript Could Do

  • Form validation before submit
  • Image rollovers (hover effects)
  • Pop-up windows
  • Simple animations
  • Browser detection

What JavaScript Couldn't Do (Yet)

  • Update page content dynamically
  • Communicate with servers
  • Complex data manipulation
  • Reliable cross-browser behavior

JavaScript was seen as a toy. "Real" applications were built server-side.


Part 6: Session and State Management

The Stateless Problem

HTTP is stateless. Each request is independent. The server doesn't remember you.

Request 1: "Show me products"       → Server: "Here are products"
Request 2: "Add item to cart" → Server: "Who are you?"

Solutions That Emerged

Cookies (1994):

Server: "Here's a cookie: session_id=abc123"
Browser: (stores cookie)
Browser: "GET /cart (cookie: session_id=abc123)"
Server: "Ah, you're user abc123. Here's your cart."

Server-side sessions:

sessions/abc123.txt:
username=john
cart=[item1, item2]
last_seen=2004-03-15

Database storage:

SELECT * FROM sessions WHERE session_id = 'abc123';
SELECT * FROM carts WHERE user_id = 42;

These patterns are still used today. Your React app's authentication probably uses cookies and sessions.


Part 7: What Worked (And Still Does)

Patterns That Survive

URL-based routing:

/products/123        → Show product 123
/users/john/posts → Show john's posts
/search?q=lemonade → Search results

Form handling:

<form action="/submit" method="POST">
<input name="email" type="text">
<button type="submit">Subscribe</button>
</form>

Template composition:

<?php include 'header.php'; ?>
<main>Page content</main>
<?php include 'footer.php'; ?>

MVC architecture (emerged in this era):

  • Model: Data and business logic
  • View: HTML templates
  • Controller: Request handling

Why Server-Side Rendering Is Back

Modern frameworks (Next.js, Remix) bring back server-side rendering because:

  • Better SEO (search engines see content)
  • Faster first paint (no JavaScript needed for initial view)
  • Works without JavaScript
  • Simpler mental model for some apps

The wheel turns.


Part 8: The Tipping Point

By 2004-2005

The web had:

  • Millions of PHP/ASP/JSP applications
  • Rich desktop-like needs
  • Users frustrated with page refreshes
  • JavaScript improving in browsers

Gmail Changes Expectations (2004)

Google launched Gmail. It felt different:

  • No page refresh when reading emails
  • Instant search
  • Smooth, app-like experience
  • Still running in the browser

How? A technique called AJAX (which we'll cover in Module 17).

The Stage Was Set

The server-side era built the foundation:

  • HTTP and URL conventions
  • Session management
  • Template-based rendering
  • Database-driven applications

But users wanted more. The AJAX revolution was about to begin.


Exercise 1: Trace a Traditional Request

Think through what happens when a user submits a form on a PHP site:

  1. User fills out form, clicks Submit
  2. List every step until they see the response
Solution
  1. User fills form, clicks Submit
  2. Browser collects form data
  3. Browser sends POST request to server (full page navigation)
  4. Server receives request
  5. PHP script runs:
    • Parses form data
    • Validates input
    • Connects to database
    • Inserts/updates data
    • Queries for page data
    • Renders complete HTML template
  6. Server sends HTML response
  7. Browser discards current page entirely
  8. Browser parses new HTML
  9. Browser loads CSS, images, JavaScript (even if same as before)
  10. Browser renders page
  11. User sees result (scroll position reset, UI state lost)

Every navigation repeated this entire cycle.


Exercise 2: Identify the Limitations

For each scenario, explain why full-page refresh is problematic:

  1. User adds item to shopping cart
  2. User submits a comment on a post
  3. User filters a product list by category
  4. Chat application showing new messages
Discussion
  1. Shopping cart: User loses scroll position, maybe in the middle of browsing. Cart update should be instant, not disruptive.

  2. Comment submission: After posting, user is back at top of page, not seeing their comment in context. Other comments they were reading are "reset."

  3. Product filtering: Every filter change = full reload. Users want to quickly toggle filters and see results update. Multi-second waits for each filter are frustrating.

  4. Chat application: Impossible with page refresh. Can't poll for new messages smoothly. User would see page flash every few seconds.


Exercise 3: Server-Side Template

Write a simple server-side template (pseudocode or PHP-like) that:

  • Shows a welcome message with username
  • Lists items in a shopping cart
  • Shows total price
Example
<html>
<body>
<h1>Welcome, <?= $user->name ?>!</h1>

<h2>Your Cart</h2>
<?php if (empty($cart->items)): ?>
<p>Your cart is empty.</p>
<?php else: ?>
<ul>
<?php foreach ($cart->items as $item): ?>
<li>
<?= $item->name ?> - $<?= number_format($item->price, 2) ?>
× <?= $item->quantity ?>
</li>
<?php endforeach; ?>
</ul>
<p><strong>Total: $<?= number_format($cart->total, 2) ?></strong></p>
<?php endif; ?>

<a href="/checkout">Proceed to Checkout</a>
</body>
</html>

Notice: All logic runs on server. Browser just displays HTML.


Key Takeaways

  1. The web started as documents — HTML files served statically

  2. CGI enabled dynamic pages — But with performance costs

  3. PHP dominated — By mixing code and HTML seamlessly

  4. Full page refresh was the only option — Every interaction reloaded everything

  5. Sessions solved statelessness — Cookies and server storage

  6. Server-side patterns persist — URLs, forms, MVC, templates

  7. User expectations grew — Desktop-like apps demanded better


What's Next

Module 17: The AJAX Revolution

You'll learn:

  • How XMLHttpRequest changed everything
  • The rise of jQuery
  • "Web 2.0" and rich internet applications
  • Why this era created both possibilities and chaos

You've completed Module 16! You now understand the web's origins. Everything that came after was a response to the limitations you've just learned about.