协议性URL

如果你的浏览器正在访问一个 HTTPS 协议的站点, 如果没有被特别指定, 那么它也会通过 HTTPS 协议来请求当前域下的静态文件. 这个策略会导致该死的 IE 浏览器弹出此页包含安全和不安全的项目警告, 所以最佳的方案是尽量让你的所有静态资源保持在同一种协议下.

当然, 如果你正在浏览本地的文件, 那么浏览器会试图使用file:///协议来请求文件.

我们通常会使用下面这样的代码来获取 Google CDN 提供的的 jQuery:

1
2
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'))</script>

我们可以看到 src 并没有指定协议名称.

从技术上而言, 这种方式在 RFC 的 3986 标准中被定义为网络路径引用(network-path reference). 对了, 准确地讲, 我们在讨论URL的时候, 尽量使用术语scheme来代替protocol(协议).

这种技巧在也可以在 css 中使用:

1
.omgomg { background: url(//websbestgifs.net/kittyonadolphin.gif); }

当然这基于你的网站能通过 HTTP 和 HTTPS 协议中的任何一种获取到网络资源.

警告!: 当你使用 link 标签或者 @import 语法获取样式表的时候, 该死的 IE7IE8 会下载两次 css 文件, 除了这俩逗比其它浏览器还算正常.

好了, 那么我们就可以理解百度统计的监视代码默认是这样的:

1
2
3
4
<script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F
{{My_Baidu_Tongji_Hash}}' type='text/javascript'%3E%3C/script%3E"));
</script>

这里的私有变量_bdhmProtocol就是当前页面使用的协议的判断.

这样我们就可以对这行代码进行优化了: 如果你的站点只支持 http 协议(当然这在国内应该是绝大部分), 不妨把上面的 js 代码改成这样:

1
2
3
<script type="text/javascript">
document.write(unescape("%3Cscript src='http%3A//hm.baidu.com/h.js%3F
{{My_Baidu_Tongji_Hash}}' type='text/javascript'%3E%3C/script%3E"));
</script>


本文翻译自4年前的一篇博文, 偶尔逛站遇到的.

原文是: The Protocol-relative URL

独立博客为我们在茫茫网海中占据一粒尘的位置, 不求访问量, 只求内心舒坦.