## 概述和歷史回顧
當(dāng)你在瀏覽器地址欄輸入 URL 的時(shí)候,你希望看到在你的瀏覽器里顯示這個(gè)網(wǎng)站。當(dāng)你點(diǎn)了一個(gè)鏈接,或者提交了一個(gè)表單,你的瀏覽器可能會(huì)顯示下一個(gè)頁面,或者在你的表單中顯示一些錯(cuò)誤提示,以便你能糾正它們并再次提交。你的瀏覽器就是一個(gè)接口,或者說一扇窗,通過她你就可以與萬維網(wǎng)進(jìn)行互動(dòng)與交互。
在你的瀏覽器的背后,有一堆文件 -- CSS,HTML,Javascript,視頻文件,圖片文件等等 -- 這些文件構(gòu)成了你所看到的頁面。所有這些東西都是通過一個(gè)叫做 HTTP 的傳輸協(xié)議從**服務(wù)器**傳輸?shù)侥愕臑g覽器,也就是**客戶端**里(所以你現(xiàn)在知道為什么在瀏覽器地址欄輸?shù)刂返臅r(shí)候前面加的是?`http://`?了吧)。
HTTP,或者超文本傳輸協(xié)議,是上世紀(jì)80年代由蒂姆.伯納斯.李發(fā)明的。它是一個(gè)規(guī)則系統(tǒng),是一種協(xié)議,把應(yīng)用程序和超文本文檔之間的傳輸聯(lián)系起來。換句話說,HTTP 就是機(jī)器之間彼此溝通的一個(gè)協(xié)議,或者說一個(gè)消息格式。HTTP 遵循一個(gè)簡(jiǎn)單的模型:從客戶端發(fā)出請(qǐng)求到服務(wù)器并等待響應(yīng)。因此它也被認(rèn)為是一種“請(qǐng)求--響應(yīng)協(xié)議”。請(qǐng)求和響應(yīng)都是文本信息,或者說是字符串,信息寫法遵循著一個(gè)規(guī)則,能保證其他機(jī)器能夠理解上面的內(nèi)容。
HTTP 協(xié)議從創(chuàng)立之初已經(jīng)經(jīng)過了一些變化。最開始的時(shí)候這個(gè)協(xié)議僅僅返回 HTML 頁面。在 1991年,第一個(gè)文檔 HTTP/0.9 發(fā)布。1992年,HTTP/1.0 發(fā)布,并支持傳輸不同的文件類型,比如 CSS 文件,視頻,腳本和圖片。1995年,HTTP/1.1 介紹了連接復(fù)用和其他的一些特性。1999年又對(duì) HTTP/1.1 做了一些改進(jìn),我們現(xiàn)在看到的就是這一版本。在撰寫本文時(shí),HTTP/2 正處于開發(fā)初期。
## 互聯(lián)網(wǎng)是如何工作的
互聯(lián)網(wǎng)是由數(shù)以百萬計(jì)的互相連接的網(wǎng)絡(luò)構(gòu)成,網(wǎng)絡(luò)中計(jì)算機(jī)和其他設(shè)備可以互相通信。按照慣例,網(wǎng)絡(luò)內(nèi)的所有設(shè)備都提供獨(dú)特的標(biāo)簽。這種標(biāo)簽的總稱是互聯(lián)網(wǎng)協(xié)議地址或 IP 地址,是類似于在互聯(lián)網(wǎng)上的計(jì)算機(jī)的電話號(hào)碼。此外,IP 地址還有端口號(hào),這會(huì)提供更多關(guān)于如何與其交流的細(xì)節(jié) (類似于分機(jī)號(hào)碼)。IP 地址一般都長(zhǎng)這樣:
~~~
192.168.0.1
~~~
當(dāng)需要一個(gè)端口號(hào)的時(shí)候,這樣:
~~~
192.168.0.2:1234
~~~
IP 地址是`192.168.0.2`,端口號(hào)是`1234`。 IP 地址是設(shè)備或服務(wù)器的標(biāo)識(shí)符,可以包含數(shù)以千計(jì)的端口,每個(gè)端口都用于不同的交互目標(biāo)。
互聯(lián)網(wǎng)是比網(wǎng)絡(luò)更大的一個(gè)概念,互聯(lián)網(wǎng)上每個(gè)設(shè)備都有?[互聯(lián)網(wǎng)服務(wù)供應(yīng)商 (ISP)](http://en.wikipedia.org/wiki/Internet_service_provider)?提供的公網(wǎng) IP 地址,通過這些地址,它們可以進(jìn)行通信。當(dāng)我們想訪問 Google 的主頁的時(shí)候,我們并沒有在瀏覽器里輸入它的 IP 地址,我們只是輸入 Google 的 URL?[http://www.google.com](http://www.google.com/),但是像?[http://www.google.com](http://www.google.com/)?這樣一個(gè)地址,你的電腦是怎么知道它的 IP 地址的呢?
## DNS
URL 和 IP 地址之間的對(duì)應(yīng)由域名解析系統(tǒng)也就是常說的 DNS 來控制。DNS 是一個(gè)分布式數(shù)據(jù)庫,把像[http://www.google.com](http://www.google.com/)?這樣的域名翻譯成 IP 地址,并將請(qǐng)求映射到遠(yuǎn)程服務(wù)器。換句話說,DNS 在互聯(lián)網(wǎng)上記錄 URL 和它對(duì)應(yīng)的 IP 地址。所以像?[http://www.google.com](http://www.google.com/)?這樣的域名會(huì)被解析成一個(gè) IP 地址`197.251.230.45`。順便提一下,通過在瀏覽器地址欄里敲 IP 地址也能訪問網(wǎng)站。
不過,比起記一串?dāng)?shù)字來說,大多數(shù)人還是喜歡使用一個(gè)用戶友好的地址如?[http://www.google.com](http://www.google.com/)?這樣的。DNS 數(shù)據(jù)庫被安裝在叫做 DNS 服務(wù)器的設(shè)備上。重要的一點(diǎn)是,DNS 服務(wù)器集群是分層級(jí)的,沒有任何一個(gè)單一的 DNS 服務(wù)器中包含所有數(shù)據(jù)。如果一個(gè) DNS 服務(wù)器里沒有一個(gè)請(qǐng)求需要的域名,這個(gè) DNS 服務(wù)器就會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給這個(gè)集群上更上一層節(jié)點(diǎn)的 DNS 服務(wù)器。最終,這個(gè)域名會(huì)在某個(gè) DNS 服務(wù)器上的數(shù)據(jù)庫里被發(fā)現(xiàn),然后它對(duì)應(yīng)的 IP 地址所代表的設(shè)備就會(huì)來接受這個(gè)請(qǐng)求。
你通過瀏覽器與互聯(lián)網(wǎng)交互的一個(gè)典型實(shí)例是這樣的:
1. 在瀏覽器里輸入類似?[http://www.google.com](http://www.google.com/)?這樣的地址。
2. 你的請(qǐng)求被發(fā)送到你設(shè)備的網(wǎng)絡(luò)接口。
3. 這個(gè)請(qǐng)求的互聯(lián)網(wǎng)之旅從搜索?[http://www.google.com](http://www.google.com/)?的 IP 地址開始。在屏幕后面,[http://www.google.com](http://www.google.com/)?代表了一個(gè)與某個(gè)遠(yuǎn)程服務(wù)器關(guān)聯(lián)的 IP 地址的人類友好的名稱。
4. 遠(yuǎn)程服務(wù)器接受請(qǐng)求并將響應(yīng)通過互聯(lián)網(wǎng)發(fā)送到你的網(wǎng)絡(luò)接口,并把它交給你的瀏覽器。
5. 最終,瀏覽器把這個(gè)響應(yīng)作為一個(gè)網(wǎng)頁的形式呈現(xiàn)在你面前。
有一點(diǎn)你要明白,當(dāng)你的瀏覽器發(fā)出請(qǐng)求的時(shí)候,它只是發(fā)送了一些文本到一個(gè) IP 地址。因?yàn)榭蛻舳?(瀏覽器) 和服務(wù)器 (請(qǐng)求接收者) 之間有一個(gè) HTTP 形式的約定,或者叫協(xié)議,這樣服務(wù)器才可以分析請(qǐng)求,了解其組成并將響應(yīng)發(fā)送回 web 瀏覽器。然后,web 瀏覽器將響應(yīng)字符串處理成你能理解的內(nèi)容。瀏覽像 Facebook,Google 和 Twitter 這樣的網(wǎng)站,就意味著你一直在使用 HTTP。這些細(xì)節(jié)都被隱藏了,你的瀏覽器會(huì)自動(dòng)處理好請(qǐng)求和響應(yīng)?;ヂ?lián)網(wǎng)的不同部分看起來像是這樣的:

## 客戶端和服務(wù)器
最常見的客戶端是你每天與之交互,被稱為 Web 瀏覽器的應(yīng)用程序。Web 瀏覽器常見的有 Internet Explorer、 火狐、 Safari,包括移動(dòng)版本。Web 瀏覽器的職責(zé)是發(fā)送 HTTP 請(qǐng)求,并將響應(yīng)處理成人類友好的形式顯示在你的顯示器上。web 瀏覽器并不是唯一的客戶端,有很多工具或者應(yīng)用都能發(fā)送 HTTP 請(qǐng)求。
你的請(qǐng)求的內(nèi)容最終的接收者是被稱為服務(wù)器的遠(yuǎn)程計(jì)算機(jī)。服務(wù)器也沒啥神秘的,就是處理請(qǐng)求的設(shè)備,它們的工作就是發(fā)送一個(gè)響應(yīng)回去。通常情況下,服務(wù)器發(fā)送回去的響應(yīng)里面都包含了請(qǐng)求中指定的一些數(shù)據(jù)。

## 資源 (Resources)
資源是一個(gè)通用術(shù)語,指的是互聯(lián)網(wǎng)上你通過 URL 與其交互的東西。包括了圖片,視頻,網(wǎng)頁和其他文件。資源并不限于文件或者網(wǎng)頁。資源也可能是一個(gè)軟件,一個(gè)炒股的軟件,一個(gè)游戲?;ヂ?lián)網(wǎng)上有無數(shù)的資源。

## 無狀態(tài)的 (statelessness)
當(dāng)一個(gè)協(xié)議設(shè)計(jì)成每一個(gè)請(qǐng)求/響應(yīng)周期與前一個(gè)都是互相獨(dú)立的話,我們就說這個(gè)協(xié)議是無狀態(tài)的。對(duì)于 HTTP 要知道的一點(diǎn)就是,無狀態(tài)協(xié)議對(duì)于服務(wù)器資源和易用性的影響。HTTP 協(xié)議下,服務(wù)器不需要在各次請(qǐng)求之間保留狀態(tài)信息。結(jié)果就是如果一次請(qǐng)求出了問題,系統(tǒng)不必做任何清理。以上兩個(gè)原因讓 HTTP 協(xié)議變的很靈活,但同時(shí)也變的很難構(gòu)建有狀態(tài)的應(yīng)用。因?yàn)?HTTP 本質(zhì)上是個(gè)無狀態(tài)的互聯(lián)網(wǎng)協(xié)議,這就意味著 web 開發(fā)人員在構(gòu)建有狀態(tài)應(yīng)用的時(shí)候,不得不努力想辦法來模擬 web 應(yīng)用中的有狀態(tài)體驗(yàn)。 舉個(gè)例子,當(dāng)你上 Facebook 的時(shí)候,你先登錄,然后你看到了一個(gè) Facebook 的網(wǎng)頁。這就是一個(gè)完整的請(qǐng)求/響應(yīng)周期。你點(diǎn)了一張照片 -- 另一個(gè)請(qǐng)求/響應(yīng)周期 -- 但是在第二個(gè)動(dòng)作之后你并沒有退出登錄。如果 HTTP 是無狀態(tài)的,它是怎么維持狀態(tài)并且知道你剛剛已經(jīng)登錄過了呢?事實(shí)上,如果 HTTP 是無狀態(tài)的,F(xiàn)acebook 是怎么知道哪個(gè)請(qǐng)求是你發(fā)出的?它是怎么區(qū)分你和其他用戶的?這些都是 web 開發(fā)人員和 web 開發(fā)框架耍的小詭計(jì),讓 web 應(yīng)用看起來像是有狀態(tài)的,不過這些小詭計(jì)不在本書的討論范圍內(nèi)。你所要記住的就是,盡管你覺得這個(gè)應(yīng)用是有狀態(tài)的,但是在它背后,這個(gè) web 應(yīng)用是構(gòu)建在 HTTP,一個(gè)無狀態(tài)協(xié)議之上的。以上,就是為什么 web 如此靈活和去中心化,同時(shí)又特別難控制,也是為什么 web 的安全性難以保證,為什么在 web 上構(gòu)建應(yīng)用不是易事。
## 小結(jié)
本章用一種簡(jiǎn)單的描述解釋了互聯(lián)網(wǎng)如何工作和幾個(gè)術(shù)語。你也學(xué)到了無狀態(tài)對(duì) web 應(yīng)用的影響。在下一章,我們會(huì)深入探討?[http://www.google.com](http://www.google.com/)?這樣的地址到底是什么以及它各部分的作用。
