我有以下元素:

<script type="text/javascript" src="https://cdn.example.com/js_file.js"></script>

在这种情况下,站点是HTTPS,但站点也可能只是HTTP。(JS文件在另一个域中。)为了方便起见,我想知道是否可以这样做:

<script type="text/javascript" src="//cdn.example.com/js_file.js"></script>

我想知道是否可以删除http:或https:?

它似乎在我测试过的所有地方都有效,但是否有任何情况下它不起作用?


当前回答

不使用协议是完全合理的。URL规范多年来一直对此非常明确,我还没有发现一个浏览器不理解这一点。我不知道为什么这个技巧不为人所知;它是跨越HTTP/HTTPS边界这一棘手问题的完美解决方案。更多信息:Http-https转换和相对url

其他回答

我在html5-boilerplate上看到的模式是:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

它可以在不同的方案上顺利运行,如http, https,文件。

有没有什么情况下它不起作用?

如果您是在本地服务器上开发,那么它可能无法工作。您需要指定一个方案,否则浏览器可能会假设src="//cdn.example.com/js_file.js"是src="file://cdn.example.com/js_file.js",这将破坏,因为您没有在本地托管这个资源。

微软ie浏览器似乎对这一点特别敏感,看这个问题:无法在本地主机上加载jQuery (WAMP)

您可能总是试图找到一种解决方案,该解决方案适用于所有环境,所需的修改最少。

HTML5Boilerplate使用的解决方案是在资源没有正确加载时有一个回退,但只有当你合并一个检查时才有效:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- If jQuery is not defined, something went wrong and we'll load the local file -->
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

更新:HTML5Boilerplate现在使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js后决定弃用协议相对url,见[这里][3]。

有没有什么情况下它不起作用?

如果父页面是从file://加载的,那么它可能无法工作(它将尝试获取file://cdn.example.com/js_file.js,当然您也可以在本地提供)。

是的,这在RFC 3986章节5.2中有记录:

(编辑:哎呀,我的RFC引用过时了)。

当使用//somedomain.com作为JS文件的引用时,我们在日志中看到404错误。

导致404的引用是这样的: 裁判:

<script src="//somedomain.com/somescript.js" />

404请求:

http://mydomain.com//somedomain.com/somescript.js

由于这些问题经常出现在我们的web服务器日志中,可以肯定地说:所有浏览器和机器人都不遵守RFC 3986第4.2节。最安全的做法是尽可能地包含协议。