我覺得有很多人并不了解 URL ( 或 URI )的全貌,一般人對URL的感覺就是「網址」而已,是一個十分不精確的描述,因為 URL 擁有一個很嚴謹的結構,也有很彈性的表示法,當你弄清楚觀念后,開發技巧之間的關係自然可以融會貫通。
我從 RFC 3986: Uniform Resource Identifier (URI): Generic Syntax 的 Syntax Components 章節摘取下圖:
image
如上圖所示,在 URI 中有切分成許多部分,每個部分都有其意義,當你瞭解其意義之后,以后在記憶 URI 的時候就不用死背了。事實上在 URI scheme - Wikipedia 頁面中的圖示更加完整,如下圖:
image
以下所列的網址(URL/URI/URN),全部都是 URI 的格式范例 (注意:并非所有 URI 在瀏覽器中都可以使用)
連結一般網站
http://blog.miniasp.com/post/2008/01/Useful-tool-grepWin.php#comment
連結需登入的 FTP 網站(直接在網址輸入帳號、密碼后,連結時瀏覽器就不會再出現登入視窗了)
password@ftp.example.com/upload/">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
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 正常運作。
在實務開發上,許多人使用「相對路徑」來簡化 URI 的表示,最后我要講幾個在開發 Web 應用程式時常用的「相對路徑」開發技巧:
技巧 1:忽略 scheme 與 authority 部分(見本文第 1 張圖示)
這也是一般常見的「相對路徑」寫法,有時后會包含「路徑」的部分,有時后僅包括「檔名」:
同目錄下的 step2.php 頁面
step2.php
網站根目錄下的 index.aspx 頁面
/index.php
上層目錄的 sitemap.aspx 頁面
../sitemap.php
上兩層目錄的 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 憑證,否則還是一樣會抓不到圖片的。
重點:href 和 src 的定義與區別
href和src是有區別的,而且是不能相互替換的。我們在可替換的元素上使用src,然而把href用于在涉及的文檔和外部資源之間建立一個關系。
href (Hypertext Reference)指定網絡資源的位置,從而在當前元素或者當前文檔和由當前屬性定義的需要的錨點或資源之間定義一個鏈接或者關系。當我們寫下:
<link href="style.css" rel="stylesheet" />
瀏覽器明白當前資源是一個樣式表,頁面解析不會暫停(由于瀏覽器需要樣式規則去畫或者渲染頁面,渲染過程可能會被被暫停)。這與把css文件內容寫在<style>標簽里不相同,因此建議使用link標簽而不是@import來吧樣式表導入到html文檔里。
src (Source)屬性僅僅 嵌入當前資源到當前文檔元素定義的位置。當瀏覽器找到
<script src="script.js"></script>
在瀏覽器下載,編譯,執行這個文件之前頁面的加載和處理會被暫停。這個過程與把js文件放到<script>標簽里類似。這也是建議把JS文件放到底部加載的原因。當然,img標簽頁與此類似。瀏覽器暫停加載直到提取和加載圖像。
與img類似的有更多: replaced elements。
結語
由此可見,網址從最右邊的 query 部分一直到 authority 部分都是可以省略的,唯一的限制是不能「跳著省略」,例如說你不能同時省略 scheme 與 path 部分。而省略過的網址就稱為「相對網址」。
今天講「網址」這種超級基礎的知識,相信還是有些人會覺得這個「小技巧」很新鮮。我時常跟我帶的人說:「擁有實務經驗十分重要,但若不懂得技術原理,成長的力道就會受限」。身為一個研發人員,不斷進修本來就是我們的宿命,除了平時要經常寫 Code 以外,花點時間看書是有必要的!
常言道:「書到用時方恨少」,所有人都知道這個道理,但又有多少人能夠身體力行呢?也許是因為工作忙碌沒時間進修,但這真的可以當藉口嗎?
- 2023-4-8__成長之路
- 技術雜談
- 程序員境界
- 走進猿類
- 做一個程序員
- 什么是猿類
- 愛亂吹的猿
- 業余生活
- 我的書架
- 高效程序員的45個習慣
- 敏捷—高效軟件開發之道
- 態度決定一切
- 學無止盡
- 交付用戶想要的軟件
- 敏捷反饋
- 敏捷編碼
- 敏捷調試
- 藝術人生
- 摘自藝術的境界
- 如何欣賞畫
- 《的》
- 我的文檔
- 小白學習前那些說不完的事
- 計算機語言都一樣
- 嘗試理解他人代碼
- 做為旁觀者的思考
- 怎樣才算懂計算機
- 工欲善其事,必先利其器
- 教案日志
- 十天學電腦
- 一,認識計算機
- 二、認識編程語言
- 三、認識程序內涵
- 四,認識數據結構
- 五、認識電腦系統
- 六、認識通信原理
- 七、郵箱管理
- 八、重新審視電腦
- 九、理解終生學習
- 十、感悟三千世界
- c語言
- C語言——我覺得好簡單
- c學好不怕沒飯碗—2014.7.21
- C語言——我想的有點兒簡單
- 或多或少的c語言知識
- c語言初探篇
- 初探c語言底層
- 初探整型和浮點型
- 初探二進制數---原反補移
- 初探有無符號
- 初探c是如何跑起來的
- 初探指針
- 初探數組
- 初探順序表
- 初探棧,隊列
- 初探c語言編程
- c語言進階篇
- c語言自身的那些事
- 結構詳解
- c語言大成篇
- 人類思維——模式匹配
- 論c語言面試
- 數據結構
- 核心概念,沒有之一順序表
- 線性表代碼實現
- Sq_list
- 不存在的鏈表
- 只是一種思想——棧
- 只是一種思想——隊列
- 不存在的樹
- 只是一種思想——二分法
- 不存在的圖
- 算法原理
- 傅里葉變換
- 算法導論
- 算法導論——c語言實現
- 算法導論——java實現
- 組成原理
- 操作系統
- 初探操作系統
- 深究操作系統
- 操作系統如何跑起來
- 進程就像細胞
- 系統就像生命
- 進程樹pstree
- 進程
- 進程何時更名為生命
- 初探進程映像
- 程序如何成為進程映像
- PCB
- PCB解讀之——信號量(p_sig)
- 進程同步
- 進程通信
- 進程調度
- 用戶
- PPDA
- 存儲系統
- I/O系統
- 網絡原理
- 通信簡史
- 通信是網絡基礎
- 趣談網絡
- 自我介紹
- 快遞公司
- 小D的自述
- 網絡架構
- OSI/RM
- 應用層
- 表示層
- 會話層
- 傳輸層
- 網絡層
- 數據鏈路層
- 物理層
- TCP/IP四層模型
- 五層模型
- 網絡劃分
- IP史
- 信息安全
- 社會工程學
- 信息收集
- 誘導
- 偽裝
- 如何成為任何人
- 社會心理學
- 思維模式
- 說服的力量
- 代碼審計
- 災難恢復
- 安全注入
- 網絡工程
- 802.11
- CCNA
- CWNA
- 社會工程
- 社會心理
- 信息誘導
- 身份偽裝
- 系統框架
- web前端框架
- smarty框架
- bootstrap框架
- thinkphp框架
- zend框架
- yii框架
- ci框架
- 網站開發
- 五大難題
- 網站工作原理
- 數據庫原理
- 服務器原理
- 前端開發
- 前端技能基礎
- html
- css
- javascript
- 瀏覽器兼容
- 前端總結
- 后臺開發
- 或多或少的JS
- js初探篇
- 理解Javascript
- JS繼承
- 數組
- 操作方法
- DOM事件
- 數據傳輸
- JS面試題
- 數據對象
- 學生管理系統
- 學生管理首頁
- 粗略學了一遍后的總結
- 零碎知識
- js初探篇第二版
- javascript構成
- 基本類型
- 基本語句與判斷類型
- 基本對象與操作函數
- 基本判斷與甄別數據
- 內置對象與操作函數
- 對象認識與深淺復制
- DOM級別與BOM
- 嚴格模式與混雜模式
- ES5和ES6
- js進階篇
- 上傳圖片
- js實戰篇
- 或多或少的PHP
- 詳解url結構
- html基礎
- html初識
- html-組成頁面的基礎標簽
- ie兼容
- 教學方法
- 論php——編程思想
- 論php——底層實現
- 中華國學
- 易經
- 黃帝內經
- 山海經
- 道德經
- 騙經
- 中華哲學
- 一花一世界
- 道可道非常道
- 一瞬
- 宇宙
- 心得體會
- 電腦叫智能生命體更準確
- 計算機不是漢語模式
- 瑣事日記
- 成長與人性
- 祝單身狗快樂
- 人其實過的很單薄
- 都怪自己不夠優秀
- 那是幾個人的世界
- 認清世界,認清自己
- 陪伴繁華逝去的平凡
- 俯拾仰取
- 技術手冊
- 網站開發
- 準備工作
- firewalld
- mysql
- redis
- 開發流程
- 整體配置
- 環境配置
- tomcat配置
- 數字證書配置
- 項目配置
- 數據設計
- 用戶管理
- 整站設計
- user
- user_group
- user_role
- 服務端
- 了解學習
- quartz
- HelloWorld
- HelloJob
- HelloQuartz
- HelloScheduler
- Job
- JobDataMap
- Trigger
- Scheduler
- properties
- spring
- AOP
- 使用
- svnkit
- svn init
- FSFS
- server
- Java
- 測試
- 任務調度
- 網站架構
- 網站前端
- pc端
- 移動端
- native
- ios
- android
- ipad
- hybrid
- 技術日志
- 2018-9-26
- 2018-11-26
- 資源收集
- UED資源
- 技術架構
- 云平臺
- 工作方面
- 實習工作經驗
- 草稿1
- 草稿2
- 草稿3
- 草稿4
- 草稿5
- 草稿6
- 草稿7
- 大學總結
- 面經
- 一、職能定位
- 細節
- 前端
- 工作總結
- 簡歷
- 職業規劃
- 一年規劃
- 整理歸檔
- 2015/11/10以前
- 2015/11/10
- 2015/11/11
- 2015/11/12
- 2015/11/13
- 2015/11/14
- 2015/11/15與16
- 2015/11/17
- 2015/11/18
- 2015/11/19與20
- 2015/11/21
- 2015/11/22
- 2015/11/23
- 2015/11/24
- 2015/11/25
- 2015/11/26
- 2015/11/27
- 2015/11/28
- 2015/11/29
- 2015/11/30-12/6
- 2015/12/7-2016/4/18
- 2016/4/19
- 2016/4/20~2017/6/27
- 2017/6/28-2017/7/4
- 2017/7/5-2018/1/11
- 2018/1/12
- 2018/1/13-2018/4/19
- 2018/4/20
- 2018/4/21-2018/5/10
- 2018/5/11
- 2018/5/12-2018/5/16
- 2018/5/17-2018/5/30
- 2018/5/30-2018/10/15
- 2018/10/15-2018/10/18
- 2018/10/19-2018/11/17
- 2018/11/17-2018/12/31
- 結束----------------開始
- 2019/2/18
- 2020/7/30
- 2020/9/5
- 2021/5/6
- 回收站
- 以前文件
- 2015-10-17__成長之路
- 2018-10-15__成長之路
- 2020-3-29__成長之路
- 畢業三年總結
- 浙大之旅
- 2020
- 英語
- 基礎3000單詞
- 第一周
- 百詞斬__126
- 百詞斬__126翻譯
- 百詞斬__252
- 百詞斬_252翻譯
- 百詞斬__392
- 百詞斬__532
- 百詞斬__672
- 第二周
- 百詞斬__812
- 聽力
- 新東方演講稿
- 庫克杜克大學演講全文版
- 庫克杜克大學演講演講英文對照版