Learning Objectives
- 分辨網際網路與全球資訊網,說出 WWW 的三個基本元件:URL、HTML、HTTP
- 拆解一個 URL:協定、主機、埠號、路徑、查詢字串、片段
- 讀懂 HTTP 請求與回應的結構:方法、狀態列、標頭、內容
- 依狀態碼的五個類別判斷結果,認得 200、301、304、403、404、500
- 說明 HTTP 為什麼需要 Cookie,以及 Set-Cookie 與 Cookie 標頭的往返
- 說明 HTTPS 保護了什麼、沒保護什麼,以及憑證的用途
按下 Enter 之後,瀏覽器在做什麼
在網址列打 https://www.example.com/ 按下 Enter,不到一秒網頁就出現了。這不到一秒裡,瀏覽器大致做了這些事:
- 用 DNS 把
www.example.com換成 IP 位址 - 和那個 IP 建立連線;網址是
https時,還要先完成加密的交握 - 送出一段 HTTP 請求:「請給我
/這個資源」 - 收到 HTTP 回應:一段 HTML 文字
- 讀 HTML,發現還需要樣式表、程式、圖片,再送出更多請求,最後把頁面畫出來
常有人把「網際網路」和「網頁」當成同一件事,其實不一樣:
| 名詞 | 是什麼 |
|---|---|
| 網際網路(Internet) | 全世界的網路互相連起來的基礎設施,用 TCP/IP 傳送封包 |
| 全球資訊網(World Wide Web,WWW) | 跑在網際網路上的一種服務:用超連結把文件串在一起,用瀏覽器瀏覽 |
電子郵件、線上遊戲、視訊會議也都跑在網際網路上,但它們不是 WWW。
1989 年 3 月,在歐洲核子研究組織(CERN)工作的 Tim Berners-Lee 提出一份文件〈Information Management: A Proposal〉, 構想用分散式的超文字系統管理研究資料。他接著做出三樣東西,到今天仍是 WWW 的骨架:
- URL:每份資源一個獨一無二的位址
- HTML:描述網頁內容與超連結的標記語言
- HTTP:瀏覽器向伺服器要資源的協定
1991 年 8 月他公開宣布這個專案,第一個網站放在 info.cern.ch;1993 年 4 月 30 日,CERN 宣布 WWW 的軟體免權利金開放給所有人使用。
這一課要回答:網址每一段是什麼意思、瀏覽器和伺服器之間到底傳了哪些文字、狀態碼怎麼讀、網站怎麼「記得你登入了」,以及 HTTPS 的鎖頭保護了什麼。
URL 的結構
一個完整的 URL(Uniform Resource Locator,統一資源定位器)長這樣,可以拆成六段:
https://www.example.edu.tw:443/courses/list?semester=1151&page=2#cs101
| 部分 | 這個網址裡的值 | 意思 |
|---|---|---|
| 協定(scheme) | https |
用什麼方式取得:http、https;也有 mailto:、ftp 等 |
| 主機(host) | www.example.edu.tw |
網域名稱或 IP 位址,DNS 會把名稱換成 IP |
| 埠號(port) | 443 |
伺服器上哪一個服務;省略時 http 用 80、https 用 443 |
| 路徑(path) | /courses/list |
伺服器上的哪一個資源,看起來像資料夾,但不一定真的對應到檔案 |
| 查詢字串(query) | semester=1151&page=2 |
? 後面的 名稱=值,用 & 隔開,常用來帶搜尋條件、頁碼 |
| 片段(fragment) | cs101 |
# 後面的部分,指頁面裡的某個位置;不會送給伺服器,由瀏覽器自己處理 |
網址裡不能直接放空白和某些符號,會被轉成 % 加兩位十六進位,例如空白是 %20;中文字會先轉成 UTF-8 的位元組,再一個位元組一個 %XX。
HTML 與瀏覽器:一個網頁其實是很多次請求
伺服器回傳的網頁是一段 HTML 文字,用標籤(tag)標出內容的結構:
<!doctype html>
<html>
<head>
<title>示範大學</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>歡迎來到我們的首頁</h1>
<p>看看<a href="/courses/list">課程列表</a>。</p>
<img src="/logo.png" alt="校徽">
<script src="/app.js"></script>
</body>
</html>
瀏覽器拿到這段文字,一邊讀一邊建立頁面的結構;讀到 style.css、logo.png、app.js,又會各自送出請求。
所以打開一個網頁,背後常常是幾十個請求;HTML 管內容與結構、CSS 管外觀、JavaScript 管互動。
<a href="…"> 就是超連結:點下去,瀏覽器對新的 URL 再走一次「DNS → 連線 → 請求 → 回應」。
HTTP 請求與回應長什麼樣子
HTTP 的訊息是有固定格式的文字(HTTP/1.1 的寫法)。一個請求:
GET /courses/list?semester=1151 HTTP/1.1
Host: www.example.edu.tw
User-Agent: ExampleBrowser/1.0
Accept: text/html
Accept-Language: zh-TW
- 第一行是請求列:方法、路徑、版本
- 接著是標頭(header),一行一個「名稱: 值」;
Host一定要有,因為同一台伺服器上可能有很多個網站 - 空一行之後是內容(body);GET 通常沒有內容,POST 送出表單時才有
一個回應:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1532
<!doctype html>
<html>…
- 第一行是狀態列:版本、狀態碼、說明文字
- 標頭告訴瀏覽器內容是什麼格式(
Content-Type)、有多長(Content-Length),以及要不要快取、要不要存 Cookie - 空一行之後是內容:HTML、圖片的位元組、JSON 資料…
常用的方法:
| 方法 | 用途 |
|---|---|
| GET | 取得資源;重新整理、點連結都是 GET |
| POST | 送出資料,例如登入、送出表單、上傳檔案 |
| HEAD | 和 GET 一樣,但只要標頭不要內容;用來檢查資源在不在、有沒有更新 |
| PUT、DELETE | 修改、刪除資源,常見於網站提供給程式使用的介面(API) |
還有一件重要的事:HTTP 是無狀態(stateless)的。伺服器處理完一個請求就忘了,下一個請求來,它不知道是不是同一個人。這一點後面講 Cookie 時會用到。
狀態碼:三位數的第一位就是類別
狀態碼看第一位數字就知道大方向:
| 類別 | 意思 | 常見的碼 |
|---|---|---|
| 1xx | 資訊:收到了,繼續 | 101 Switching Protocols |
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 轉址或「用你手上的」 | 301 Moved Permanently、302 Found、304 Not Modified |
| 4xx | 用戶端的問題:請求本身不對 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found |
| 5xx | 伺服器的問題:請求沒錯,伺服器處理失敗 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable |
幾個容易混淆的:
- 301 與 302:都會附上
Location標頭,瀏覽器自動改去新網址;301 表示永久搬家(搜尋引擎會更新記錄),302 表示暫時。 - 304:瀏覽器問「我快取裡這份(ETag 是
"v1")還是最新的嗎?」伺服器回「沒變」,不必再傳一次內容,省下頻寬與時間。 - 401 與 403:401 是「你還沒證明你是誰」,403 是「我知道你是誰(或不需要知道),但你不能看」。
- 404 與 500:404 是你要的東西不存在;500 是伺服器的程式自己出錯,同一個請求換個時間可能就好了。
想一想:URL、訊息與狀態碼
瀏覽器開啟 https://www.example.com/news?page=3#comments,下面哪一部分不會出現在送給伺服器的 HTTP 請求裡?
網站把 /old-page 永久搬到 /new-page,伺服器應該回什麼,瀏覽器才會自動跳過去?
選課系統在選課當天回傳 503 Service Unavailable。這是誰的問題?
Cookie:讓無狀態的 HTTP 記得你
HTTP 是無狀態的,那網站怎麼知道「你已經登入了」?靠 Cookie:
(登入時,伺服器的回應)
HTTP/1.1 200 OK
Set-Cookie: session=s8f3a91c2; Path=/; HttpOnly; Secure
(之後瀏覽器每一個送到同一個網站的請求)
GET /me HTTP/1.1
Host: www.example.com
Cookie: session=s8f3a91c2
- 你登入成功,伺服器產生一個不容易猜到的代號(session ID),用
Set-Cookie交給瀏覽器 - 瀏覽器把它存起來,之後送到這個網站的請求都自動帶上
Cookie標頭 - 伺服器看到代號,查到「這是 student 的登入」,於是認得你
Cookie 常見的屬性:
| 屬性 | 意思 |
|---|---|
Expires/Max-Age |
存多久;沒寫就是關掉瀏覽器時刪除 |
Path、Domain |
哪些網址的請求要帶上它 |
Secure |
只在 HTTPS 連線時送出 |
HttpOnly |
網頁裡的 JavaScript 讀不到,降低被惡意程式偷走的風險 |
也因為這樣,拿到別人的 session Cookie,就等於可以冒充他登入,所以 Cookie 一定要在加密的連線上傳送。 另外,網頁裡嵌入其他網站的廣告或追蹤元件時,那些網站也可以設定自己的 Cookie(第三方 Cookie),用來跨網站追蹤你的瀏覽行為; 現在的瀏覽器多半提供限制或封鎖第三方 Cookie 的設定。
HTTPS:加密、防竄改、確認對方是誰
HTTP 的訊息是明文。在咖啡店、車站的公共 Wi-Fi 上,同一個網路裡的人有機會看到你送出的請求,包括密碼與 Cookie; 如果有人假冒成路由器或伺服器(中間人攻擊),甚至可以偷偷改掉網頁內容。
HTTPS 是把 HTTP 放進 TLS(Transport Layer Security)加密連線裡傳送,HTTP 訊息本身的格式不變。TLS 提供三件事:
| 保護 | 意思 |
|---|---|
| 機密性 | 內容加密,旁人只看到亂碼 |
| 完整性 | 內容被改過,接收的一方會發現 |
| 身分驗證 | 伺服器出示憑證,證明自己真的是 www.example.com |
憑證(certificate)像是網站的身分證:寫著網域名稱、公開金鑰、有效期間,由憑證機構(Certificate Authority,CA)用數位簽章背書。 瀏覽器和作業系統內建一份信任的憑證機構清單;憑證的名稱對不上、過期、或不是由信任的機構簽發,瀏覽器就會顯示警告並停下來。
HTTPS 也有它沒有保護的東西:
- 你連到哪個 IP、哪個網站名稱、傳了多少資料,網路上的人還是看得到
- 鎖頭只代表「連線加密、對方確實擁有這個網域」,不代表網站可信;釣魚網站也可以申請到自己網域的憑證,所以還是要看清楚網址
網址列的 https:// 與鎖頭圖示,現在幾乎是所有網站的基本配備;瀏覽器對 http:// 的網站會標示「不安全」。
HTTP 的版本
HTTP 從 1991 年到現在改過好幾版,方法、狀態碼、標頭的意義大致不變,改的主要是「怎麼在網路上傳送」:
| 版本 | 規格 | 重點 |
|---|---|---|
| HTTP/0.9 | 1991 年的最初版本(當時沒有版本號,後來才這樣稱呼) | 只有 GET,回應就是 HTML,沒有狀態碼與標頭 |
| HTTP/1.0 | RFC 1945(1996 年 5 月) | 加入狀態碼、標頭、POST 等;每個請求開一條新連線 |
| HTTP/1.1 | RFC 2068(1997 年 1 月),之後由 RFC 2616 等修訂 | 連線可以重複使用;Host 標頭成為必要,一台伺服器可以放很多網站 |
| HTTP/2 | RFC 7540(2015 年 5 月) | 改用二進位的訊框,多個請求在同一條連線上同時進行 |
| HTTP/3 | RFC 9114(2022 年 6 月) | 改在 QUIC 上傳送,QUIC 跑在 UDP 上,連線建立更快 |
2022 年 6 月的 RFC 9110 把各版本共用的語意(方法、狀態碼、標頭)整理成一份。 這一課的模擬器用 HTTP/1.1 的文字格式顯示訊息,因為最容易閱讀;用 HTTP/2、HTTP/3 時,同樣的內容換成二進位格式傳送。
想一想:Cookie 與 HTTPS
你登入網站後,伺服器怎麼在下一個請求認出你?
在公共 Wi-Fi 上用 https:// 登入網站。同一個網路上的竊聽者看不到哪一項?
一個網址列有鎖頭圖示的網站,下面哪一個說法正確?
重點整理
- 網際網路是基礎設施,全球資訊網(WWW)是跑在上面的一種服務;1989 年 3 月 Berners-Lee 在 CERN 提出構想,骨架是 URL、HTML、HTTP。
- URL:協定
://主機:埠號 路徑?查詢字串#片段;片段不會送給伺服器,http預設埠 80、https預設 443。 - 一個網頁常需要很多次請求:HTML 之外還有 CSS、JavaScript、圖片。
- HTTP 請求=請求列(方法、路徑、版本)+標頭+內容;回應=狀態列(版本、狀態碼、說明)+標頭+內容。
- 狀態碼看第一位:2xx 成功、3xx 轉址或用快取、4xx 請求有問題、5xx 伺服器出錯。
- HTTP 是無狀態的;登入狀態靠
Set-Cookie與Cookie標頭維持,session Cookie 被偷就等於帳號被冒用。 - HTTPS=HTTP+TLS:加密、防竄改、用憑證確認伺服器身分;網站名稱與流量大小仍然看得到,鎖頭不代表網站可信。
- HTTP/1.1、HTTP/2、HTTP/3 的語意相同,差在傳送方式。
下一課:網站要放在哪裡執行?我們來看雲端運算:虛擬化、IaaS/PaaS/SaaS,以及「用多少付多少」。
想自己寫網頁,可以接著上 JavaScript 軌;想寫伺服器端的程式,可以看 PHP 軌。