Что означает двойной слеш в URL?

32

Что в точности означает двойная косая черта, часто встречающаяся в URL?

Например:

  • http://www.example.com/A/B//C/

Обратите внимание, что я не имею в виду начало сразу после http:.

aneuryzm
источник

Ответы:

32

Это ошибка в коде программистов / разработчиков. Если вы сравните эти два URL:

  • http://www.example.com/A/B/C/
  • http://www.example.com/A/B//C/

Они выглядят по-разному, но если бы вы посетили либо оба, они будут работать в большинстве современных браузеров.

Это то, что вы хотите исправить. Если у вас двойная косая черта, это может сбить с толку веб-сканеров Google и заставить их думать, что существует 2 версии страницы.

Бен Хоффман
источник
11
На самом деле, загрузка страницы не имеет ничего общего с браузером , но сервер игнорирует лишнюю косую черту. Это стало длинным, так что смотрите ответ, который я разместил.
josh3736
33

Как уже упоминалось @RandomBen , двойная косая черта, скорее всего, является результатом ошибки где-то.

То, что страница загружается, не имеет ничего общего с браузером , но сервер игнорирует лишнюю косую черту. Браузер не делает ничего особенного с дополнительными косыми чертами в URL, он просто отправляет их вместе в запросе:

GET /A/B//C/D HTTP/1.1
Host: www.example.com
...

Похоже, что текущие версии Apache и IIS будут игнорировать дополнительные косые черты при определении пути и возвращать документ, который был бы возвращен, если бы в URL не было лишних косых черт. Тем не менее , браузеры (я тестировал IE 8 и Chrome 9) запутываются из-за относительных URL-адресов (содержащих компоненты родительского пути) ресурсов на странице, что приводит к плохим результатам. Например, если страница имеет:

<link rel="stylesheet" href="../../style.css" type="text/css" />

После загрузки страницы /a/b/c/браузер запросит /a/style.css. Но если - по какой-либо причине /a/b//c/- запрашивается (а сервер игнорирует лишнюю косую черту), браузер в итоге запросит /a/b/style.css, которого не будет. К сожалению, страница выглядит ужасно.

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

Это мое мнение , что Apache и IIS (и , возможно , другие) действуют неправильно , как /a/b/c/и /a/b//c/технически представляют собой два различных ресурсов. Согласно RFC 2396 каждый слэш имеет значение:

  path          = [ abs_path | opaque_part ]

  path_segments = segment *( "/" segment )
  segment       = *pchar *( ";" param )
  param         = *pchar

  pchar         = unreserved | escaped |
                  ":" | "@" | "&" | "=" | "+" | "$" | ","

Итак, /a/b/c/состоит из трех сегментов: «а», «б» и «с»; /a/b//c/на самом деле состоит из четырех: "a", "b", "" (пустая строка) и "c". Является ли пустая строка допустимым каталогом файловой системы, зависит от платформы сервера. (И по логике это означает, что браузеры действительно работают правильно при разборе относительных URL-адресов с родительскими компонентами пути - в моем примере они идут выше каталога «c» и каталога «», оставляя нам запрос style.cssиз «b».)

Если вы используете Apache с mod_rewrite, есть довольно простое решение :

# remove multiple slashes anywhere in url 
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$ 
RewriteRule . %1/%2 [R=301,L] 

Это приведет к 301 Moved Permanentlyперенаправлению HTTP, так что любые двойные слэши будут удалены из URL.

josh3736
источник
2
Не лучше ли, чтобы ваше mod_rewriteрешение учитывало 3, 4, ... косые черты? Что-то вроде /{2,}? (Предполагая, что Apache допускает такой квантификатор, я не слишком знаком с ним)
Ward Muylaert
+1 - Спасибо за дополнительную информацию. Я не думал об этом таким образом!
Бен Хоффман
3
Это не неправильное поведение: a/bи в a//bсамом деле два различных пути URL, но ничто не запрещает серверу возвращаться один и тот же ресурс для них обоих , если она хочет. Однако я согласен с вами, что на практике возврат перенаправления 301 представляется более полезным.
Ильмари Каронен
4
@IlmariKaronen: Это абсолютно неправильное поведение, потому что (1) это поведение автоматически создает бесконечное количество потенциальных дублирующих ссылок на один ресурс (который, если не нарушает букву какой-либо спецификации, безусловно, нарушает дух), и более практично (2) он «нарушает» обработку относительного пути в браузерах, которые правильно считают пустую строку в a//bкачестве каталога (см. Пример таблицы стилей выше).
josh3736
1
... и в любом случае, я бы утверждать , что RFC 2396 действительно запрещает сервер возвращаться один и тот же ресурс на авто сворачивания косых черт , потому что спецификация говорит , что каждый слэш имеет большое значение. Автоматическое игнорирование последовательных слешей является нарушением этой спецификации. (Одно дело, если кто-то запрограммирует на этом свой сервер, даже если это будет глупо. Однако серверы, делающие это по умолчанию , некорректны.)
josh3736
4

Двойная косая черта имеет значение, когда она используется в URL ресурсов. Например, когда это пользователь в CSS для URL фонового изображения:

.classname {
    background : url("//example.com/a/b/c/d.png");
}

Здесь это означает, что это фоновое изображение извлекается из другого домена, отличного от домена текущей веб-страницы. Или, другими словами, http://может быть написано как только //при использовании этого в URL ресурсов.

Но эта двойная косая черта между URL (например /a//b/c/d.htm:) не имеет никакого значения.

Алан Джозеф
источник
ну, это не вся правда Двойная косая черта используется, когда необходимо избежать проблем со смешанным содержимым, поэтому, когда сайт загружается из http, двойной слэш расширяется до http, а когда сайт загружается из https, двойной слэш расширяется до https.
Андрей
2

Как уже упоминалось, некоторые серверы настроены на игнорирование двойной косой черты в пути URL, но статический хостинг Amazon S3 не будет. Если вы хотите обрабатывать / игнорировать их в этом случае, вы можете использовать Правила перенаправления на панели свойств.

Если вы хотите игнорировать двойную косую черту после имени домена, вы можете использовать что-то вроде этого:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyPrefixWith/>
    </Redirect>
  </RoutingRule>
</RoutingRules>

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

orlade
источник