我有以下元素:

<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

其他回答

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

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

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

404请求:

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

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

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

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

它保证可以在任何主流浏览器上运行(我没有考虑市场份额低于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。

1. 总结

2019年的答案是:你仍然可以使用相对于协议的url,但这种技术是反模式的。

另外:

你可能在发展方面有问题。 一些第三方工具可能不支持它们。

从协议相对的url迁移到https://,这将是很好的。


2. 相关性

这个答案与2019年1月有关。在未来,这个答案的数据可能会被淘汰。


3.反模式

3.1. 论证

Paul Irish -前端工程师和谷歌Chrome的开发倡导者-在2014年12月写道:

既然SSL是鼓励所有人使用的,并且没有性能问题,那么这种技术现在是一种反模式。如果您需要的资产在SSL上可用,那么总是使用https://资产。 允许代码片段通过HTTP请求,为最近的GitHub man -on- side攻击打开了大门。即使您的站点是在HTTP上,请求HTTPS资产也总是安全的,然而反过来就不正确了。

3.2. 另一个链接

使用协议相对uri加载页面资源 停止使用协议相对url

3.3. 例子

2017年,Stack Overflow从相对协议的url切换到https 2018年Chrome将把所有未加密的网站标记为“不安全”


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,阅读Thilo和bg17aw关于file://的回答。

我不知道这种行为,也不明白为什么我的页面会出现这样的问题。


5. 第三方工具

我使用可点击的url崇高的文本包。使用它,我可以简单地打开链接从我的文本编辑器在浏览器。

示例中的两个链接都有效。但第一个链接,我可以成功地打开浏览器使用点击url,第二个链接-没有。这可能不太方便。


6. 结论

Yes:

如果您在开发流程项中遇到问题,您可以设置开发工作流。 如果你在第三方工具项目中遇到问题,你可以贡献工具。

但是你不需要这些额外的问题。通过反模式项中的链接读取信息:协议相对url已过时。

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

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