統一資源識別符 (URI)

(1-3) 統一介面 (Uniform Interface) 中,我們介紹:
「HTTP 透過 Client 發送 請求 (Request),Server 送出 回應 (Response) 以進行互動。」
 
 

那 請求 的 目標 (target) 與 目的 (purpose) 是?

 
譬如去書局,我們可能
目標: 『JavaScript 從入門到放棄』這本書,
目的: 『JavaScript 從入門到放棄』這本書。
 
本篇主要說明 HTTP 請求的『目標』。
 


 

統一資源識別符 (URI)

Client 送出請求的目標 (target) 是?

資源 (resource) !!

 

何謂 資源 (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 位址,並藉此訪問:
dns-example
 
注意:

就算 host 名稱正確,也不代表一定會有 HTTP 應用

 

子網域

網域名稱 中,也包含了能依 網域擁有者 自行設定的 子網域 (Subdomain)
如最常見的 www (唸法: triple w)、本站的 blog (NotFalse.net)、
內容傳遞網路 常使用的 cdn、或其他的 apimailtw …等等:
 
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 的 UrlEncodeurlencodeURLEncoder 則是 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=搜尋內容&.....

     
     

作者: 鄭中勝
喜愛音樂,但不知為何總在打程式 ? 期許能重新審視、整理自身所學,幫助有需要的人。

發表迴響