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


458

我有以下要素:

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

在我测试过的所有地方似乎都可以使用它,但是在某些情况下它不起作用?


2
可以将“它似乎无处不在”推广到图片,iframe,链接关联等吗?如果是这样,这是有趣的东西。
12345

是的,它应该可以在需要URI的任何地方工作:图像,链接等。虽然很少见到使用它,但是它是完全有效的。
杰夫

1
所有那些即时支持的家伙怎么办?并不是说这个问题是坏的还是什么,我只是很好奇。但是我敢打赌克里斯的个人声誉会产生影响。
Frederik Wordenskjold

13
@Frederik:因为这是一个有趣而有用的技巧,大多数人显然没有意识到。
Slaks 2010年

8
@Frederik:什么?
SLaks 2010年

Answers:


387

根据RFC 3986:“统一资源标识符(URI):通用语法”,第4.2节,不带方案的相对URL(http:或https :)有效。如果客户端对此感到窒息,那是客户端的错,因为它们不符合RFC中指定的URI语法。

您的示例有效,应该可以工作。我本人在人流量大的网站上使用了这种相对URL方法,并且零投诉。另外,我们在Firefox,Safari,IE6,IE7和Opera中测试我们的网站。这些浏览器都了解该URL格式。


30
“如果客户端对此感到窒息,那是客户端的错,因为它们不符合RFC中指定的URI语法。” -我认为这是一个有趣的问题-但是,对于在Web应用程序中是否明智,客户是否遵循“规范”几乎不是一个好的标准。
马特·豪威尔

6
尽管这种技术似乎鲜为人知,但所有Web浏览器都支持该技术。效果很好。
Ned Batchelder

8
我不知道为什么Google不将其用于分析。他们使用document.location.protocol方法。
Darryl Hein

5
@Darryl Hein我相信Google使用document.location.protocol方法,因为它还修改了URL,而不仅仅是方案。如果文档使用https方案,他们将访问SSL.google-analytics.com
尼克·梅尔德鲁姆

18
google不使用此功能,因为Windows XP网络堆栈不支持SNI。参见此处:blogs.msdn.com/b/ieinternals/archive/2009/12/07/…。因此,允许通过IE6上的https加载Google Analytics(分析)脚本会导致证书错误。
Eilistraee'2

152

它保证可以在任何主流浏览器中使用(我没有考虑市场份额低于0.05%的浏览器)。哎呀,它可以在Internet Explorer 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
是的,我想我认为方案和权威始终是相互依赖的。并非如此,但直到最近我才遇到。
克里斯(Chris

1
不保证可以在任何浏览器中使用。保证只能在遵循RFC的浏览器中工作。

2
@Roger Pate:我还没有看到浏览器不遵循RFC的URI。那个特定的标准已经存在了很长时间……我刚刚在IE3.0中对其进行了测试,并且它理解得很好。如果您使用的浏览器不了解这些链接,则可能是因为这种边缘浏览器无关紧要。
Andrew Moore 2010年

1
@Andrew:也许您与我有所不同,但是当我在编程的上下文中说“保证”时,我的意思是“这是不可能的,永远不会失败的,”不仅仅是“它仅在我喜欢的流行实现中起作用”经过测试。” 我本来不是要做很多事情,但是它似乎很重要。

4
@Roger:是的,但是在Web开发的背景下,没有考虑边缘浏览器(市场份额<0.01%)。这就像在Windows的所有版本中都存在一个API,然后有人说它可能在Wine中不受支持...
Andrew Moore 2010年

79

在某些情况下它不起作用?

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


19
对于在本地计算机上测试html的人来说必须知道!
Philip007

啊...难怪我script src="//..."没有工作!我正在本地打开html文件!
wisbucky 2014年

有人知道解决这个问题的方法吗?
km6zla 2015年

@ ogc-nick:您可以运行本地Web服务器。如今,配置为零的选项很多。无论如何,您还是希望如此,因为其他许多事情(例如XHR或Web worker也不适用于该文件:域)
Thilo 2015年

@Thilo一直在为我工作,但是我正在用Github的Electron制作一个应用程序,这变得有些复杂。
km6zla


25

在这里,我重复了HTML的隐藏功能中的答案:

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

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

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

这样可以防止IE中出现可怕的“此页面同时包含安全和非安全项目”错误消息,从而使所有资产请求都保持在同一协议内。

注意:在<link>样式表的@import上使用IE7和IE8 两次下载文件。但是,所有其他用途都很好。


17

放弃该协议是完全有效的。多年来,URL规范对此非常清楚,但我还没有找到一个不了解它的浏览器。我不知道为什么这种技术没有更好的了解;它是解决HTTP / HTTPS边界棘手问题的完美解决方案。更多信息:Http-https转换和相对URL


7

在某些情况下它不起作用?

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

Microsoft Internet Explorer似乎对此特别敏感,请参阅以下问题:无法在localhost(WAMP)的Internet Explorer中加载jQuery

您可能总是会尝试找到一种在您的所有环境中都能以最少的修改量运行的解决方案。

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后使用,请参阅[here] [3]。


4

遵循gnud的参考之后,RFC 3986第5.2节说:

如果定义了方案组件,则表明引用以方案名称开头,那么该引用将被解释为绝对URI,我们就完成了。否则,参考URI的方案将从基本URI的scheme组件继承

所以//是正确的:-)


3

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

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


3

正如其他答案所言,这确实是正确的。不过,您应该注意,某些网络搜寻器会通过在您的服务器上请求它们(就像本地URL)来触发404。(他们无视双斜杠并将其视为单斜杠)。

您可能想在您的Web服务器上设置一条规则以捕获并重定向它们。

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

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

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

此外,这是为每个查询运行的一个相当大的正则表达式-我认为,值得对不兼容的浏览器使用404惩罚,因为大多数兼容浏览器的性能(略有下降)。


3

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

导致404出现的引用看起来像这样:ref:

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

404要求:

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

随着这些定期显示在我们的Web服务器日志中,可以肯定地说:所有浏览器和Bot 都不遵守RFC 3986第4.2节。最安全的选择是在可能的情况下包括该协议。


是的,我有点远离它了,但不是因为404(我从未见过任何404 ...如果一个机器人不遵守它,我就不在乎)–因为我不再从其他CDN,因此我不需要这样做(相反,我尽可能地缩小为1或2个文件)。
Darryl Hein 2014年

1
请包括协议。无协议引用在我的Cordova应用程序中中断。
pgorsira 2015年

3

1.总结

2019年答案:您仍然可以使用协议相对URL,但是此技术 是反模式

也:

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

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


2.相关性

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


3.反模式

3.1。论证

保罗爱尔兰- 前端工程师和开发人员倡导者的谷歌浏览器 - 在2014年,月写

现在,所有人都应该鼓励使用 SSL 并且不必担心性能问题现在这种技术已成为一种反模式。如果您需要的资产在SSL上可用,请始终使用https://资产。

允许代码段通过HTTP请求打开了诸如最近的GitHub Man-on-the-side攻击之类的攻击之门。即使您的站点位于HTTP上,请求HTTPS资产始终是安全的,但是事实并非如此

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并阅读有关Thilobg17aw的答案file://

我不知道这种行为,也无法理解为什么我在pageres中遇到这样的问题。


5.第三方工具

我使用Clickable URLs Sublime Text软件包。使用它,我可以简单地从浏览器中的文本编辑器中打开链接。

CSS链接示例

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


六,结论

是:

  1. 如果您有任何问题Developing process,可以设置开发工作流程。
  2. 否则,您可能会遇到其他问题Third-party tools,您可以提供工具。

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


2

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


这不再是真的,请参见stackoverflow.com/a/37609402/2237601在此处,它们现在已https://用于所有内容
bg17aw

@ bg17aw在https://所有地方使用的问题是,然后您必须继续检查所有外部链接,以查看它们是否真正支持它,并将其更改为http://不支持(否则它们将无法工作)。使用大量链接可能会很麻烦。
tomasz86 '17

@ tomasz86您遗漏了要点,我只是参考了从CDN链接到内容的特殊情况。如今,https://是必需的。答案还讨论了一种特殊情况(html5-样板)。正如您所说,没有“检查http”,因为CDN现在始终使用https。
bg17aw

@ bg17aw是的,但是这里的一般问题不仅是关于CDN。通过仅阅读此答案/评论,很容易想到https://应该(或可以)在所有不正确的链接中使用。
tomasz86 '17

@ tomasz86拥有多个答案的美妙之处在于,尽管没有一个答案是完美的(如果一个答案是完美的,则其他答案将需要删除),阅读其中的一些可以为我们提供更广阔的视野。在这种情况下,答案说“ html5boilerplate上的模式是...”,而我的评论更新了此答案并提到“不再是html5-boilerplate上的模式”。而已。此特定答案的必要补充。还请注意,原始问题确实与CDN有关!
bg17aw

1

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

另外,在更新旧网站时进行了测试,并且还可以在META REFRESH的url =部分中使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.