在脚本src="http://...">中将http://替换为//是否有效?

我有以下元素:

<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:?

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

128030 次浏览

没有方案的相对URL (http:或https:)是有效的,根据RFC 3986:“统一资源标识符(URI):通用语法”,章节4.2。如果客户端阻塞了它,那么这是客户端的错,因为它们没有遵守RFC中指定的URI语法。

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

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

许多人称之为协议相对URL。

它会导致IE 7中CSS文件的双重下载;8

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

使用协议无关的绝对值 路径:< / p >

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

如果浏览器正在浏览某个页面 SSL通过HTTPS,然后它会请求 有HTTPS协议的资产, 否则它会用HTTP请求

这可以防止可怕的“此页面” 同时包含安全的和非安全的 项目”错误信息在IE,保持 中的所有资产请求 同样的协议。< / p > 警告:当用于<link>或 样式表的@import, IE7和IE8 下载文件两次。所有其他的

是的,这在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。

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

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

在gnud引用之后,RFC 3986第5.2节表示:

如果定义了scheme组件,则表示引用 以方案名开始,然后引用被解释为 绝对URI,我们就完成了。否则,引用URI的方案 继承自基URI的scheme组件.

所以//是正确的:-)

这的确是正确的,正如其他答案所陈述的那样。但是你应该注意,一些网络爬虫会通过在你的服务器上请求它们来设置404,就像一个本地URL一样。(他们忽略了双斜杠,将其视为单斜杠)。

你可能想要在你的web服务器上设置一个规则来捕捉这些并重定向它们。

例如,在Nginx中,你可以添加如下内容:

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

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

而且,对于每个查询来说,这是一个相当庞大的正则表达式——在我看来,对于大多数兼容的浏览器来说,用404来惩罚不兼容的浏览器是值得的。

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

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

导致404的引用是这样的: 裁判:< / p >
<script src="//somedomain.com/somescript.js" />

404请求:

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

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

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

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

微软的Internet Explorer似乎对此特别敏感,请看这个问题:无法在本地主机的Internet Explorer中加载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]。

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

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

1. 总结

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

另外:

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

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


2. 相关性

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


3.反模式

3.1. 论证

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

现在SSL是<坚强的>鼓励大家没有性能问题这种技术现在是一种反模式。如果您需要的资产在SSL上可用,则始终使用https://资产。

允许代码段通过HTTP进行请求为诸如recent GitHub man -on- side attack .之类的攻击打开了大门。请求HTTPS资产总是安全的,即使你的网站是在HTTP上,然而相反的不是true

3.2. 另一个链接

  • 使用协议相对uri加载页面资源
  • < a href = " https://joonas。fi/2016/12/27/ Stop -using-protocol-relative- URLs /" rel="noreferrer">停止使用协议相对url . fi/2016/12/27/ Stop -using-protocol-relative- URLs /" rel="noreferrer">

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://< >强Thilo < / >强< >强bg17aw < / >强的答案。

我不知道这种行为,也不明白为什么我有像这是pageres这样的问题。


5. 第三方工具

我使用< <强>点击url /强> Sublime Text包。使用它,我可以简单地打开链接从我的文本编辑器在浏览器。

CSS links examples

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


6. 结论

是的:

  1. 如果你在Developing process项目中遇到问题,你可以设置你的开发工作流。
  2. 如果你遇到类似Third-party tools item的问题,你可以贡献工具。

但是你不需要这些额外的问题。通过Anti-pattern item:协议相对url中的链接读取信息已过时。