在 (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
authority 是 URI 中用來識別網路存取端點的元件,通常由 host 與可選 port 組成;它不保證該主機就是最終 origin,也不是對回應內容的權威性判斷。DNS、CDN、proxy、load balancer 與 virtual hosting 都可能介入。
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 的語法由 URI 規範與各應用共同決定。保留字元可以作為結構分隔符號;只有當它是資料的一部分、不能被當成分隔符號解讀時,才應 percent-encode。percent-encoding 是以 UTF-8 等字元編碼得到的 octet,再把每個 octet 寫成
%HH;例如:為%3A,空白為%20。+不是通用 URI 的空白替代,而是application/x-www-form-urlencoded慣例。
中文等非 ASCII 字元也需先轉為 UTF-8 octets,再 percent-encode;瀏覽器常替你處理,但程式碼應使用 URI/URL API,而非手動字串替換。
開發時,需 記得處理 query 字串 (尤其是 客戶端應用),
以免送出保留字元或錯誤的編碼。
許多程式語言,都有現成 API 支援;重點是逐一處理 query 的 key 與 value,不要把整條 URI(連同://、/、?)丟進去編碼。
如 JavaScript,可用URLSearchParams組出 query:var params = new URLSearchParams({ q: query }); var result = params.toString();
C#、PHP、Java 的UrlEncode、urlencode、URLEncoder則是application/x-www-form-urlencoded慣例,適合表單或 query 的單一欄位;空白通常會編成+。它們不是通用的「URI 編碼器」,更不該用來編碼完整 URI。String result = URLEncoder.encode(query, StandardCharsets.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=搜尋內容&.....