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

它在我测试过的所有地方似乎都可以使用,但是在任何情况下都无法使用?

凯L2020/03/20 10:11:52

1. Summary

Answer for 2019: you can still use protocol-relative URLs, but this technique an anti-pattern.

Also:

  1. You may have problems in developing.
  2. Some third-party tools may not support them.

Migrating from protocol-relative URLs to https:// it would be nice.


2. Relevance

This answer is relevant for January 2019. In the future, the data of this answer may be obsolete.


3. Anti-pattern

3.1. Argumentation

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

Now that SSL is encouraged for everyone and doesn’t have performance concerns, this technique is now an anti-pattern. If the asset you need is available on SSL, then always use the https:// asset.

Allowing the snippet to request over HTTP opens the door for attacks like the recent GitHub Man-on-the-side attack. It’s always safe to request HTTPS assets even if your site is on HTTP, however the reverse is not true.

3.2. Another links

3.3. Examples


4. Developing process

For example, I try to use clean-console.

  • Example file 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>
  • output:
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

Link //cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js is valid, but I getting an error.

Pay attention to file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js and read Thilo and bg17aw answers about file://.

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


5.第三方工具

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

CSS链接示例

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


六,结论

是:

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

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

乐米亚2020/03/20 10:11:52

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

附带说明一下,在更新旧网站时进行了测试,并且还可以在META REFRESH的url =部分中使用。

乐千羽2020/03/20 10:11:52

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

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

所以//是正确的:-)

小小2020/03/20 10:11:52

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

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

阿飞泡芙2020/03/20 10:11:52

使用//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节。最安全的选择是在可能的情况下包括该协议。

神乐阿飞Itachi2020/03/20 10:11:52

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

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

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

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

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

而且,这是为每个查询运行的一个相当大的正则表达式-我认为,值得对404兼容的不兼容浏览器进行惩罚,而不是对大多数兼容浏览器造成(轻微)性能下降。

猴子樱2020/03/20 10:11:52

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

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

樱Harry2020/03/20 10:11:52

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

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

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

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

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

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

逆天古一2020/03/20 10:11:52

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

这会导致在IE 7和8中双重下载CSS文件

GOGil老丝2020/03/20 10:11:52

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

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

番长村村2020/03/20 10:11:52

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

理查德Tom2020/03/20 10:11:52

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

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

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

When defining relative URIs (Section 5.2), you can omit any of those sections, always starting from the left. In pseudo-code, it looks like this:

 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;

The URI you are describing is a scheme-less relative URI.