## 簡介
當你想去某人家里的時候,你要知道他家的地址。如果你想給你朋友打電話,你要知道你朋友的電話號碼。沒有這些信息,你想去別人家或者給人打電話都是不可能的。換句話說,如果你有別人的住址或者電話號碼,你能立刻知道誰是誰,因為地址和電話號碼都有其唯一性。
在互聯網上尋找和訪問服務器也是同樣的一個概念。當你想上 Facebook 的游戲站的時候,你會打開瀏覽器然后輸入?[http://www.facebook.com/games](http://www.facebook.com/games)。web 瀏覽器向這個地址發送一個 HTTP 請求,然后拿回這個地址的響應結果。你剛剛輸入的那個地址,[http://www.facebook.com/games](http://www.facebook.com/games)?就是所謂的統一資源定位符 (Uniform Resource Locator) 或 URL。URL 就像是你跟你朋友溝通所需要的電話號碼或者地址一樣的存在。URL 應該是統一資源標識符 (Uniform Resource Identifier) 這個籠統的概念的一種最常見的形式。本章我們討論什么是 URL 及其組成部分,和對你這個 web 開發者來說 URL 意味著什么。
## URL 組成部分
當你看到一個 URL,比如`http://www.example.com/home`,其實是由幾個組件構成的。我們可以把這個 URL 分解成 3 部分:
* `http`:通常被稱為 URL 模式( scheme )。總是出現在冒號和兩個斜杠之前,作用是告訴 web 客戶端怎樣去訪問一個資源。在本例中,它告訴 web 客戶端使用超文本傳輸協議也就是 HTTP 去發起一個請求。常見的 URL 模式還有`ftp`,`mailto`和`git`。
* `www.example.com`:URL 的第二個部分,就是資源路徑或主機 (host)。它告訴客戶端,資源的確切位置。
* `/home/`:URL 的第三個部分就是 URL 路徑。它代表了客戶端正在請求什么樣的本地資源 (對于服務器來說)。

有時候,這個路徑指向了一個主機上特定的資源。比如,`www.example.com/home/index.html`指向了 example.com 服務器上的一個 HTML 文件。
另外,URL 可以包含一個主機用來監聽 HTTP 請求的端口號。一個`http://localhost:3000/profile`這樣的 URL,通過 3000 端口去監聽 HTTP 請求。web 客戶端用來監聽 HTTP 請求的默認端口號是 80,如果一個 URL 中沒有指定其他的端口號,那就等價于寫了80?**除非指定了其他的端口號代替,不然端口號80會被默認用于正常的 HTTP 請求**。
## 查詢字符串 / 參數
一個查詢字符串或者參數是 URL 的一部分并且通常都包含一些要發往至服務器的各種類型的數據。一個簡單的帶查詢字符串的 URL 長這樣:
~~~
http://www.example.com?search=ruby&results=10
~~~
讓我們拆開來看看:
| 查詢字符串組件 | 描述 |
| --- | --- |
| ? | 這是個保留字,標識著查詢字符串的開始 |
| search=ruby | 這是一個參數的鍵/值對兒 |
| & | 這是個保留字,需要給查詢字符串添加參數時使用 |
| results=10 | 這也是一個參數的鍵/值對兒 |
現在我們再來看一個例子。假設我們有下面這個 URL:
~~~
http://www.phoneshop.com?product=iphone&size=32gb&color=white
~~~

在上面這個例子里,鍵/值對兒`product=iphone`,`size=32gb`,`color=white`?通過 URL 傳給了服務器。這個請求告訴`www.phoneshop.com`的服務器,把要請求的資源條件限制在`產品 iphone`,`大小 32gb`和`顏色白色`。服務器怎么樣使用這些參數取決于服務端的應用的處理邏輯。
另一個經常見到查詢字符串的情況是當你在搜索引擎上搜索東西的時候。**因為查詢字符串是通過 URL 傳遞的,他們僅使用 HTTP 的 GET 請求**。在本書后面的章節里我們會討論不同的 HTTP 請求,但是現在你所需要知道的是,當你不論什么時候在瀏覽器的地址欄里輸入網址進行瀏覽的時候,你就是在發起 HTTP 的 GET 請求。大部分超鏈接都是 HTTP 的 GET 請求,偶爾會有一些例外。

使用查詢字符串向服務器傳遞附加信息是個很棒的方法,但是對于查詢字符串的使用,以下是一些限制:
* 查詢字符串有最大長度。所以,如果你大量的數據需要傳輸,還是不要用查詢字符串的好。
* 查詢字符串中使用的鍵/值對兒是顯示在 URL 上的。所以,不推薦用查詢字符串傳輸敏感信息比如用戶名或密碼。
* 查詢字符串中無法使用空格和特殊字符比如`&`。它們必須用 URL 編碼代替,我們接下來會討論這個。
## URL 編碼 (URL Encoding)
URL 在設計的時候就默認只接受 ASCII 碼。因此,不安全的或者不是 ASCII 碼的字符就要進行轉義或者編碼來適應這個格式。URL 編碼的原理是將不符合格式的字符替換成`%`開頭后面跟著兩個十六進制數字代表的 ASCII 碼的一串字符。
下面是一些常見的 URL 編碼和實例 URL:
| 字符 | ASCII 碼 | URL |
| --- | --- | --- |
| space | 020 | [http://www.thedesignshop.com/shops/tommy%020hilfiger.html](http://www.thedesignshop.com/shops/tommy%020hilfiger.html) |
| ! | 041 | [http://www.thedesignshop.com/moredesigns%041.html](http://www.thedesignshop.com/moredesigns%041.html) |
| + | 053 | [http://www.thedesignshop.com/shops/spencer%053.html](http://www.thedesignshop.com/shops/spencer%053.html) |
符合下列條件的字符都要進行編碼處理:
1. 沒有對應的 ASCII 碼。
2. 字符的使用是不安全的。比如`%`就是不安全的,因為它經常用于對其它字符進行轉義。
3. 字符是有特殊用途的 URL 模式保留字。有些字符用于保留字是有著特殊的意義;它們在 URL 中的存在具有特殊用途。比如`/`,`?`,`:`,和`&`,都是需要進行編碼的保留字。
比如`&`被保留用于查詢字符串的分隔符。`:`也被保留用于分隔主機/端口號和用戶名/密碼。
那么什么樣的字符能在 URL 里安全地使用呢?只有字母表里的和`$-_.+!'(),"`這些字符可以。如果保留字符被用于它應有的特殊用途,那么是可以不用編碼的,不然也是必須要編碼的。
## 小結
本章,我們討論了什么是 URL。也認識了 URL 的組件并以對 URL 編碼的探索結尾。在準備工作章節之后,我們會稍微深入一點,一起去看看請求和響應,還有它們的構成。