The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

講解 URL 結構與分享幾個相對路徑與絕對路徑的開發技巧

我覺得有很多人並不瞭解 URL ( 或 URI ) 的全貌,一般人對 URL 的感覺就是「網址」而已,是一個十分不精確的描述,因為 URL 擁有一個很嚴謹的結構,也有很彈性的表示法,當你弄清楚觀念後,開發技巧之間的關係自然可以融會貫通。

我從 RFC 3986: Uniform Resource Identifier (URI): Generic SyntaxSyntax Components 章節擷取下圖:

URL 基本結構 

如上圖所示,在 URI 中有切分成許多部分,每個部分都有其意義,當你瞭解其意義之後,以後在記憶 URI 的時候就不用死背了。事實上在 URI scheme - Wikipedia 頁面中的圖示更加完整,如下圖:

URL 基本結構 (點圖可放大) 

以下所列的網址(URL/URI/URN),全部都是 URI 的格式範例 (注意:並非所有 URI 在瀏覽器中都可以使用)

連結一般網站
http://blog.miniasp.com/post/2008/01/Useful-tool-grepWin.aspx#comment

連結需登入的 FTP 網站(直接在網址輸入帳號、密碼後,連結時瀏覽器就不會再出現登入視窗了)
ftp://username:password@ftp.example.com/upload/

使用 Windows Live Messenger 中附的 LiveCall 工具撥打電話到 +886-2-23222480
livecall:+886-2-23222480

使用 Skype 軟體撥打電話到 +886-2-23222480
callto:+886-2-23222480

取得 FTP 上的一個檔案
ftp://ftp.is.co.za/rfc/rfc1808.txt

以 HTTP 通訊協定取得網站上的一個檔案
http://www.ietf.org/rfc/rfc2396.txt

使用 LDAP 通訊協定取得一個物件
ldap://[2001:db8::7]/c=GB?objectClass?one

使用 mailto 協定發送訊息給 John.Doe@example.com
mailto:John.Doe@example.com

連結到 comp.infosystems.www.servers.unix 新聞群組
news:comp.infosystems.www.servers.unix

撥打電話到 +1-816-555-1212
tel:+1-816-555-1212

使用 telnet 連線到 192.0.2.16:80
telnet://192.0.2.16:80/

這是 URN 語法 (也是 URI 的一部份)
urn:oasis:names:specification:docbook:dtd:xml:4.1.2

以上講解的都是「絕對路徑」的「標準」表示法,在真實的世界裡,URI 可以說千變萬化,不照標準走的大有人在,而在 URL normalization 這篇文章中有說明如何將 URL 進行「正規化」處理。所幸這類正規化的處理在 Browser 中幾乎都先幫我們處理過了,讓我們不至於真的要瞭解這麼多技術的細節才能讓 Web 正常運作。不過若自己在 Server 端處理 URI 格式的字串就不得不小心了,還好在 .NET 中有 System.Uri 類別UriBuilder 類別 幫我們處理掉了許多操作 Uri 的細節。

在實務開發上,許多人使用「相對路徑」來簡化 URI 的表示,最後我要講幾個在開發 Web 應用程式時常用的「相對路徑」開發技巧:

技巧 1:忽略 scheme 與 authority 部分(見本文第 1 張圖示)

這也是一般常見的「相對路徑」寫法,有時後會包含「路徑」的部分,有時後僅包括「檔名」:

# 同目錄下的 step2.aspx 頁面
step2.aspx

# 網站根目錄下的 index.aspx 頁面
/index.aspx

# 上層目錄的 sitemap.aspx 頁面
../sitemap.aspx

# 上兩層目錄的 default.htm 頁面
../../default.htm

# 上層目錄下的 images 目錄下的 dot 目錄下的 red.gif 檔案
../images/dot/red.gif

技巧 2:忽略 scheme 與 authority 與 path 部分

我個人常用此技巧。

連 path (含檔名) 都忽略的技巧十分好用,也就是當在同一個頁面中要指定不同的 QueryString 參數時,我就會用此技巧,範例如下:

# 跳到第 2 頁
<a href="?pageNo=2">第 2 頁</a>

# 變更 sortby 參數的值
<a href="?sortby=filesize">File Size</a>

技巧 3:忽略 scheme 與 authority 與 path 與 query 部分

此技巧也就是所謂的「頁內連結」或「書籤」,不算是技巧,是一種常見的表示法。最常用的地方就是在頁面中加上「回頁首」功能,範例如下:

<a href="#top">Top</a>
當頁面中找不到 top 這個「書籤」時,預設就會跳到本頁的最上方。

技巧 4:僅忽略 scheme 的部分

此法比較少見,但十分適用於網站內經常遊走於 HTTP 與 HTTPS 之間的網頁。

一般較大型的網站,會將網站內的圖片、影片、CSS、或 JavaScript 檔案統一放置在不同主機或不同網域下,以縮短網頁載入的時間(相關技巧可參照我之前寫的 加速前端網頁效能的14條規則 文章),通常這類的寫法會撰寫完整的「絕對路徑」,例如 Yahoo! 奇摩 的首頁 ( http://tw.yahoo.com/ ) 的 Logo 圖檔 ( http://l.yimg.com/tw.yimg.com/i/tw/hp/spirit/yahoo_logo.gif ) 就放在不同的網域下。

若我們假設今天 http://tw.yahoo.com/ 網址將改成 https://tw.yahoo.com/ 時,若頁面內的圖檔網址一樣是 http:// 開頭的網址時,使用者的瀏覽器就會出現「這個畫面同時含有安全性與非安全性的項目。要顯示非安全性項目?」的警示訊息,如下圖示(以 IE 為例):

安全性資訊 :: 這個畫面同時含有安全性與非安全性的項目。要顯示非安全性項目?

一般較講究安全的網站,會在進行會員登入、註冊、或進行線上刷卡時,特別將網址轉向到 https 頁面(SSL),這是因為使用 SSL 連線對伺服器會造成一定程度的負擔,所以通常只會在傳輸重要資料時才會進行 SSL 加密連線,但這時網站中的所有圖檔若不在同一台主機時就可以套用此技巧,如下範例:

<img src="//l.yimg.com/tw.yimg.com/i/tw/hp/spirit/yahoo_logo.gif" />

這時若你連到的網頁是 https://tw.yahoo.com/ 時,當讀取圖檔時也會預設採用 https 這個 scheme,這樣就不會產生「安全性資訊」的警示訊息了。 若以此範例來說,你的 l.yimg.com 主機當然也要啟用 HTTPS 功能以及安裝 SSL 憑證,否則還是一樣會抓不到圖片的。

結語

由此可見,網址從最右邊的 query 部分一直到 authority 部分都是可以省略的,唯一的限制是不能「跳著省略」,例如說你不能同時省略 scheme 與  path 部分。而省略過的網址就稱為「相對網址」。

今天講「網址」這種超級基礎的知識,相信還是有些人會覺得這個「小技巧」很新鮮。我時常跟我帶的人說:「擁有實務經驗十分重要,但若不懂得技術原理,成長的力道就會受限」。身為一個研發人員,不斷進修本來就是我們的宿命,除了平時要經常寫 Code 以外,花點時間看書是有必要的!

常言道:「書到用時方恨少」,所有人都知道這個道理,但又有多少人能夠身體力行呢?也許是因為工作忙碌沒時間進修,但這真的可以當藉口嗎?

相關連結