在 (1-3) 統一介面 (Uniform Interface) 中,我們介紹:
「HTTP 透過 Client 發送 請求 (Request),Server 送出 回應 (Response) 以進行互動。」
譬如去書局,我們可能
目標: 『JavaScript 從入門到放棄』這本書,
目的: 買『JavaScript 從入門到放棄』這本書。
本篇主要說明 HTTP 請求的『目標』。
目錄
統一資源識別符 (URI)
Client 送出請求的目標 (target) 是?
資源 (resource) !!
可能是一個檔案、資料庫的查詢結果、另一群資源的集合、
抽象的服務、『非虛擬』的物件(ex: 人)…
任何能被命名的資訊,都是 — 資源 (resource)。
HTTP 沒有限制資源的種類,只定義與資源交互的介面。
其中,統一資源識別符 (Uniform Resource Identifier, URI),
即「辨識 資源 的方式」,為 REST 架構風格 中的四個介面約束之一 :
資源的識別 (identification of resources)
URI 又可細分為:
- 統一資源定位符 (Uniform Resource Locator, URL)
- 統一資源名稱 (Uniform Resource Name, URN)
URL 描述了資源主要的訪問機制,以「定位資源」,如: 網址,
URN 維持了資源全域的唯一名稱 (儘管資源已不存在或不可用)。
許多文件與規範 (包含 HTTP),
使用較通用的 URI,而非限制性較強的 URL、URN,
而 程式語言 則提供 URL 的 API 居多。
常見如:
ftp://xxx.xxx.xxx.xxx
tel://+8869xxxxxxxx
在這,簡單來說就是 網址 啦~
只有瀏覽器,是沒用的,
還需要透過 HTTP URI,來指定 目標資源。
URI 方案 (URI Scheme)
網址格式大家應該都很熟悉啦 😂,但我還是列出其定義:
(許多 API,都會遇到這些專有名詞)
http(s) URI =
"http(s):" "//" authority path-abempty [ "?" query ] [ "#" fragment ]
Ex:
https://echo.paw.cloud:443/hello/world?age=24&gender=female#Uehara
小知識:
冒號 (:) 唸作 colon [ˋkolən],斜線 (/) 唸作 slash [slæʃ],
點 (.) 唸作 dot [dɑt],井號 (#) 唸作 hash [hæʃ]。
權威/管理機構 (authority),
為此名稱 (位址),真正具有『權限』送出回應者。
簡單說就是:
主機名稱 + TCP 連接埠 啦 !
格式如下:
host [ ":" port ]
host
主機 (host),包含 網域名稱 與 IP 位址 (e.g., google.com、172.217.27.142)。
若使用的是經註冊的網域名稱 (Domain Name),
例: 「example.org」、「NotFalse.net」…,
會先透過 名稱解析服務 (ex: DNS),
找到 Server (或 代理、閘道、負載平衡器) 的 IP 位址,並藉此訪問:
注意:
就算 host 名稱正確,也不代表一定會有 HTTP 應用
子網域
網域名稱 中,也包含了能依 網域擁有者 自行設定的 子網域 (Subdomain),
如最常見的 www (唸法: triple w)、本站的 blog (NotFalse.net)、
內容傳遞網路 常使用的 cdn、或其他的 api、mail、tw …等等:
Ex:
https://api.github.com
https://www.github.com
[":"port]
連接埠 (port),若無特別指定,預設是 80 port,
(台灣常見唸法為 八零ㄆㄡˋ)
若是 https 則預設為 443 port,
欲指定其他埠號需須根據 Server 之個別規範。
詳見 維基百科
[userinfo "@"]
對不起我騙了你 😓,真正的 authority 格式應為:
[ userinfo "@" ] host [ ":" port ]
userinfo — 使用者資訊,
用於一些,有支援 URI 認證機制的 Origin Server ,
也就是將帳密寫在網址上…😐 由於安全性,相對非常少見。
2014 年,為 RFC 2616 更新的 HTTP/1.1 規範 — — [RFC 7230],
說明 Userinfo 不准使用 (disallowed),
因此,為避免誤導,上方才沒列出啦!
path-abempty
可以為空,或是以 “/” 開始的路徑。
[ "?" query ]
查詢 (query), 以「?」開始,
並接著 key=value 的鍵值對 (中間別忘了加 =),
若還有其他 query ,則通常以「&」做為區隔,
是提供給 Server 參數的方式之一。
譬如: ?age=24&gender=female
代表的可能是,我想在這個網站 (如果有支援)尋找:
『年紀 24 且 性別是女性 』。
需要注意的是:
- 如果 query 字串中,包含 保留字元 (Reserved),
例如 「@」、「:」、「/」、「?」、「%」、「=」、「 」(空白) … ,必須使用"%" HEXDIG HEXDIG
HEXDIG 代表的是 hexadecimal digits,以 UTF-8 編碼的 十六進制 位數,
例如: 「:」表示為 「%3A」,這是 URI 規範中的 百分比編碼 (Percent-Encoding),也就是俗稱的 URI (URL) 編碼。 - 若保留字元是 「 」(空白),其百分比編碼表示為: 「%20」,可替代為「+」 。
- 為了一致性,十六進制的英文部分,以『大寫』為主
- 正常形式不需進行編碼
開發時,需 記得處理 query 字串 (尤其是 客戶端應用),
以免送出保留字元或錯誤的編碼。
許多程式語言,都有現成 API 支援。
如 JavaScript:
var result = encodeURIComponent(query);
C#:
String result= HttpUtility.UrlEncode(query);
PHP :
<?php
$result = urlencode(query);
Java:
String result = URLEncoder.encode(query, "UTF-8");
[ "#" fragment ]
片段 (fragment),是輔助資源,通常為主要資源的一部份或子集,
可以按 這邊 (#uri) 感受一下 (觀察網址列的變化)。
fragment,是由 Client 端 (通常為瀏覽器) 處理的部分,並 不會傳遞給 Server !
因此,HTTP 規範所說的 — 目標 URI (target URI),不包含 片段 (fragment) 部分。
一個經典範例 — Google 搜尋:
https://www.google.com.tw/?gws_rd=ssl#q=搜尋內容
送出的內容其實為:
https://www.google.com.tw/search?q=搜尋內容&.....