Допустимо ли заменить http: // на // в <script src = "http: // ...">? - PullRequest
451 голосов
/ 15 февраля 2009

У меня есть следующий элемент:

<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 ]

383 голосов
/ 15 февраля 2009

Относительный URL-адрес без схемы (http: или https :) действителен для RFC 3986: «Универсальный идентификатор ресурса (URI): общий синтаксис», раздел 4.2 . Если клиент его подавляет, то это вина клиента, поскольку он не соответствует синтаксису URI, указанному в RFC.

Ваш пример действителен и должен работать. Я сам использовал этот метод относительных URL на сайтах с интенсивным трафиком и у меня не было жалоб. Также мы тестируем наши сайты в Firefox, Safari, IE6, IE7 и Opera. Все эти браузеры понимают этот формат URL.

150 голосов
/ 04 июня 2010

Гарантируется работа в любом основном браузере (я не беру браузеры с долей рынка менее 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 без схемы.

77 голосов
/ 19 октября 2011

Есть ли случаи, когда это не работает?

Если родительская страница была загружена из file://, то, вероятно, она не работает (она попытается получить file://cdn.example.com/js_file.js, что, конечно, вы также можете предоставить локально).

40 голосов
/ 04 июня 2010

Многие называют этот протокол относительным URL.

Это вызывает двойную загрузку файлов CSS в IE 7 & 8 .

23 голосов
/ 04 июня 2010

Здесь я дублирую ответ в Скрытые возможности HTML :

Использование независимого от протокола абсолютного Путь:

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

Если браузер просматривает страницу в SSL через HTTPS, тогда он будет запрашивать этот актив с протоколом https, в противном случае он запросит его по HTTP.

Это предотвращает это ужасно "Эта страница Содержит как безопасный, так и небезопасный Предметы "сообщение об ошибке в IE, сохраняя все ваши запросы активов в пределах тот же протокол.

Предупреждение: при использовании на <link> или @import для таблицы стилей, IE7 и IE8 скачать файл дважды . Все остальные использование, однако, просто отлично.

16 голосов
/ 15 февраля 2009

Это совершенно справедливо, чтобы оставить протокол. Спецификация URL была очень ясной в течение многих лет, и мне еще предстоит найти браузер, который этого не понимает. Я не знаю, почему эта техника не более известна; Это идеальное решение сложной проблемы пересечения границ HTTP / HTTPS. Подробнее здесь: Http-https переходы и относительные URL

6 голосов
/ 03 июня 2016

Есть ли случаи, когда это не работает?

Просто добавьте это в смесь, если вы разрабатываете на локальном сервере, это может не сработать. Вам нужно указать схему, в противном случае браузер может предположить, что src="//cdn.example.com/js_file.js" равно src="file://cdn.example.com/js_file.js", что приведет к поломке, поскольку вы не размещаете этот ресурс локально.

Microsoft Internet Explorer, кажется, особенно чувствителен к этому, см. Этот вопрос: Невозможно загрузить jQuery в Internet Explorer на локальный хост (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].

3 голосов
/ 13 апреля 2012

Следуя указаниям gnud, в разделе 5.2 1001 * RFC 3986 говорится:

Если компонент схемы определен, указывая, что ссылка начинается с имени схемы, затем ссылка интерпретируется как абсолютный URI, и мы сделали. В противном случае, схема ссылочного URI наследуется от компонента схемы базового URI .

То есть // правильно: -)

2 голосов
/ 29 мая 2014

Мы видим 404 ошибки в наших журналах при использовании //somedomain.com в качестве ссылок на файлы JS.

Ссылки, которые приводят к тому, что 404-е выглядят так: ссылка:

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

404 запрос:

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

С их регулярным отображением в журналах нашего веб-сервера можно с уверенностью сказать, что: Все браузеры и боты НЕ соблюдают RFC 3986, раздел 4.2. Самым безопасным вариантом является включение протокола, когда это возможно.

2 голосов
/ 03 сентября 2013

Это действительно правильно, как утверждают другие ответы. Однако вы должны заметить, что некоторые веб-сканеры установят для них значение 404, запрашивая их на своем сервере, как если бы они были локальными. (Они игнорируют двойную косую черту и рассматривают ее как одну косую черту).

Возможно, вы захотите настроить правило на своем веб-сервере, чтобы перехватывать их и перенаправлять.

Например, с Nginx вы добавите что-то вроде:

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

Обратите внимание, что если вы используете периоды в своих URI, вам нужно будет повысить специфичность, иначе произойдет перенаправление этих страниц на несуществующие домены.

Кроме того, это довольно большое регулярное выражение для каждого запроса - на мой взгляд, стоит наказывать несовместимые браузеры с 404-ыми за (незначительное) снижение производительности в большинстве совместимых браузеров.

...