HTTP

統一資源識別符 (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),
為此名稱 (位址),真正具有『權限』送出回應者。
 
簡單說就是:

主機名稱 + TCP 連接埠 啦 !

 
格式如下:

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 字串中,包含 保留字元 (Reserved)
    例如 「@」、「:」、「/」、「?」、「%」、「=」、「 」(空白) … ,必須使用

    "%" HEXDIG HEXDIG

    HEXDIG 代表的是 hexadecimal digits,以 UTF-8 編碼的 十六進制 位數,
    例如: 「:」表示為 「%3A」,這是 URI 規範中的 百分比編碼 (Percent-Encoding),也就是俗稱的 URI (URL) 編碼。

  • 若保留字元是 「 」(空白),其百分比編碼表示為: 「%20」,可替代為「+」 。
  • 其他特殊字元,如中文 (大部分為 3個位元組),譬如: 「勝」表示為「%E5%8B%9D」,
    大部分瀏覽器網址列允許中文,是因為它幫你做好了❗️
    (複製下來在別處貼上,則會顯示 百分比編碼)
  • 為了一致性,十六進制的英文部分,以『大寫』為主
  • 正常形式不需進行編碼

 

開發時,需 記得處理 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=搜尋內容&.....


 
 

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

發表迴響