在<script src =“http:// ...”>?</script>中用//替换http://是否有效

时间:2009-02-15 00:15:19

标签: html http https uri protocol-relative

我有以下元素:

<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:是否有效?

它似乎可以在我测试的任何地方使用,但是在任何情况下它都不起作用吗?

14 个答案:

答案 0 :(得分:382)

根据RFC 3986: "Uniform Resource Identifier (URI): Generic Syntax", Section 4.2,没有方案的相对URL(http:或https :)有效。如果客户端阻塞它,那么它就是客户端的错误,因为它们不符合RFC中指定的URI语法。

您的示例有效且应该有效。我自己在交通繁忙的网站上使用过这种相对网址方法而没有投诉。此外,我们在Firefox,Safari,IE6,IE7和Opera中测试我们的网站。这些浏览器都了解URL格式。

答案 1 :(得分:149)

保证可以在任何主流浏览器中使用(我不会考虑市场份额低于0.05%的浏览器)。哎呀,它适用于Internet Explorer 3.0。

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

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

定义相对URI(Section 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。

答案 2 :(得分:77)

  

是否有任何不起作用的情况?

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

答案 3 :(得分:40)

许多人将此称为协议相对URL。

It causes a double-download of CSS files in IE 7 & 8

答案 4 :(得分:23)

我在这里复制Hidden features of HTML中的答案:

  

使用与协议无关的绝对值   路径:

<img src="//domain.com/img/logo.png"/>
     

如果浏览器正在查看页面   SSL通过HTTPS,然后它会请求   使用https协议的资产,   否则它会用HTTP请求它。

     

这可以防止这个糟糕的“本页   包含安全和非安全   项目“在IE中的错误消息,保持   您的所有资产请求   相同的协议。

     

警告:在<link>上使用时   @import用于样式表,IE7和IE8   download the file twice。所有其他   然而,用途很好。

答案 5 :(得分:16)

放弃协议是完全有效的。 URL规范多年来一直非常清楚,我还没有找到一个不理解它的浏览器。我不知道为什么这种技术不为人所知;它是跨越HTTP / HTTPS边界的棘手问题的完美解决方案。更多信息:Http-https transitions and relative URLs

答案 6 :(得分:6)

  

是否有任何不起作用的情况?

只是把它放在混合中,如果你在本地服务器上进行开发,它可能无法正常工作。您需要指定一个方案,否则浏览器可能会认为src="//cdn.example.com/js_file.js"src="file://cdn.example.com/js_file.js",由于您未在本地托管此资源,因此会暂停。

Microsoft Internet Explorer似乎对此特别敏感,请参阅此问题:Not able to load jQuery in Internet Explorer on localhost (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,请参阅[此处] [3]。

答案 7 :(得分:3)

根据gnud的参考, RFC 3986第5.2节说:

  

如果定义了方案组件,则表明该引用   以方案名称开头,然后将引用解释为   绝对URI,我们完成了。 否则,引用URI的方案   继承自基URI的方案组件

所以//是正确的: - )

答案 8 :(得分:2)

是的,RFC 3986第5.2节

中记录了这一点

(编辑:糟糕,我的RFC参考已过时)。

答案 9 :(得分:2)

正如其他答案所述,这确实是正确的。但是,您应该注意,某些网络抓取工具会通过在服务器上请求它们来为这些网站抓取404,就像本地网址一样。 (他们无视双斜线并将其视​​为单斜线)。

您可能需要在网络服务器上设置规则以捕获这些规则并重定向它们。

例如,使用Nginx,您可以添加以下内容:

location ~* /(?<redirect_domain>((([a-z]|[0-9]|\-)+)\.)+([a-z])+)/(?<redirect_path>.*) {
  return 301 $scheme:/$redirect_domain/$redirect_path;
}

请注意,如果您在URI中使用句点,则需要增加特异性,否则最终会将这些页面重定向到不存在的域。

此外,对于每个查询来说,这是一个相当大规模的正则表达式 - 在我看来,值得惩罚不符合标准的浏览器,而且大多数兼容浏览器的性能都会受到(轻微)性能的影响。

答案 10 :(得分:2)

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

导致404s的引用看起来像这样: 参考:

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

404请求:

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

在我们的网络服务器日志中定期显示这些内容时,可以肯定地说:所有浏览器和机器人不要遵守RFC 3986第4.2节。最安全的选择是尽可能包括协议。

答案 11 :(得分:1)

我在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>

它可以在httphttpsfile等不同方案上顺利运行。

答案 12 :(得分:0)

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

在附注中,在更新旧网站时进行了测试,并且还在META REFRESH的url =部分中进行了测试。

答案 13 :(得分:0)

1。摘要

2019年的答案:您仍然可以使用相对协议的URL,但使用this technique an anti-pattern

也:

  1. 您可能在开发中遇到问题。
  2. 某些第三方工具可能不支持它们。

从协议相关的URL迁移到https://会很好。


2。相关性

此答案与2019年1月相关。将来,此答案的数据可能已过时。


3。反模式

3.1。争论

Paul Irish — front-end engineer and a developer advocate for the Google Chrome-write in 2014, December

  

现在SSL为encouraged for everyonedoesn’t have performance concerns该技术现在是一种反模式。如果您需要的资产在SSL上可用,请始终使用https://资产。

     

允许代码段通过HTTP请求打开了recent GitHub Man-on-the-side attack之类的攻击之门。即使您的网站位于HTTP上,也始终可以安全地请求HTTPS资产,但是反向is not true

3.2。另一个链接

3.3。例子


4。开发过程

例如,我尝试使用clean-console

  • 示例文件KiraCleanConsole__cdn_links_demo.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>clean-console without protocol demonstration</title>
    <!-- Really dead link -->
    <script src="https://unpkg.com/bowser@latest/bowser.min.js"></script>
    <!-- Package exists; link without “https:” -->
    <script src="//cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
    <!-- Package exists: link with “https:” -->
    <script src="https://cdn.jsdelivr.net/npm/gemini-scrollbar/index.js"></script>
</head>
<body>
    Kira Goddess!
</body>
</html>
  • 输出:
D:\SashaDebugging>clean-console -i KiraCleanConsole__cdn_links_demo.html
checking KiraCleanConsole__cdn_links_demo.html
phantomjs: opening page KiraCleanConsole__cdn_links_demo.html

phantomjs: Unable to load resource (#3URL:file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js)


phantomjs:   phantomjs://code/runner.js:30 in onResourceError
Error code: 203. Description: Error opening //cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js: The network path was not found.

  phantomjs://code/runner.js:31 in onResourceError

phantomjs: Unable to load resource (#5URL:https://unpkg.com/bowser@2.1.0/bowser.min.js)


phantomjs:   phantomjs://code/runner.js:30 in onResourceError
Error code: 203. Description: Error downloading https://unpkg.com/bowser@2.1.0/bowser.min.js - server replied: Not Found

  phantomjs://code/runner.js:31 in onResourceError

phantomjs: Checking errors after sleeping for 1000ms
2 error(s) on KiraCleanConsole__cdn_links_demo.html

phantomjs process exited with code 2

链接//cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js有效,但出现错误。

请注意file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js,并阅读有关file://的{​​{3}}和Thilo答案。

我不知道这种行为,也无法理解为什么我遇到诸如bg17aw之类的问题。


5。第三方工具

我使用this for pageres Sublime Text软件包。使用它,我只需在浏览器中从文本编辑器中打开链接即可。

CSS links examples

示例中的两个链接均有效。但是,我可以使用可单击的URL在浏览器中成功打开的第一个链接,第二个链接-不。这可能不太方便。


6。结论

是:

  1. 如果您在Developing process项中遇到问题,则可以设置开发工作流程。
  2. 如果您在Third-party tools项中遇到问题,则可以提供工具。

但是您不需要其他问题。通过Anti-pattern项中的链接读取信息:相对于协议的URL已过时。