我有以下元素:

<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:)是有效的,根据RFC 3986:“统一资源标识符(URI):通用语法”,章节4.2。如果客户端阻塞了它,那么这是客户端的错,因为它们没有遵守RFC中指定的URI语法。

你的例子是有效的,应该可以工作。我自己在访问量很大的网站上使用过相对URL方法,没有人抱怨。此外,我们还在Firefox、Safari、IE6、IE7和Opera上测试我们的网站。这些浏览器都能理解URL格式。

其他回答

在这里,我在HTML的隐藏特性中复制了答案:

Using a protocol-independent absolute path: <img src="//domain.com/img/logo.png"/> If the browser is viewing an page in SSL through HTTPS, then it'll request that asset with the https protocol, otherwise it'll request it with HTTP. This prevents that awful "This Page Contains Both Secure and Non-Secure Items" error message in IE, keeping all your asset requests within the same protocol. Caveat: When used on a <link> or @import for a stylesheet, IE7 and IE8 download the file twice. All other uses, however, are just fine.

它保证可以在任何主流浏览器上运行(我没有考虑市场份额低于0.05%的浏览器)。见鬼,它适用于ie 3.0。

RFC 3986定义URI由以下部分组成:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

当定义相对uri(章节5.2)时,你可以省略这些部分,总是从左边开始。在伪代码中,它看起来像这样:

 result = ""

  if defined(scheme) then
     append scheme to result;
     append ":" to result;
  endif;

  if defined(authority) then
     append "//" to result;
     append authority to result;
  endif;

  append path to result;

  if defined(query) then
     append "?" to result;
     append query to result;
  endif;

  if defined(fragment) then
     append "#" to result;
     append fragment to result;
  endif;

  return result;

您描述的URI是一个无方案的相对URI。

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

如果您是在本地服务器上开发,那么它可能无法工作。您需要指定一个方案,否则浏览器可能会假设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]。

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

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

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

404请求:

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

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

由于您的示例链接到外部域,如果您使用的是HTTPS,那么您应该验证外部域也为SSL设置了。否则,您的用户可能会看到SSL错误和/或404错误(例如,旧版本的Plesk将HTTP和HTTPS存储在单独的文件夹中)。对于cdn,这应该不是一个问题,但对于任何其他网站,这可能是一个问题。

另一方面,在更新旧网站时进行测试,也可以在META REFRESH的url=部分中工作。