我觉得有很多人并不了解 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
- 听力
- 新东方演讲稿
- 库克杜克大学演讲全文版
- 库克杜克大学演讲演讲英文对照版