Co oznacza podwójny ukośnik w adresach URL?

32

Co dokładnie oznaczają podwójne ukośniki w adresach URL?

Na przykład:

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

Pamiętaj, że nie odnoszę się do początku zaraz po http:.

aneuryzm
źródło

Odpowiedzi:

32

To jest błąd w kodzie programistów / programistów. Jeśli porównasz te dwa adresy URL:

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

Wyglądają inaczej, ale gdybyś je odwiedził, oba działałyby w większości nowoczesnych przeglądarek.

To jest coś, co chcesz naprawić. Jeśli masz podwójny ukośnik, może pomylić roboty indeksujące Google i sprawić, że będą myśleć, że istnieją 2 wersje strony.

Ben Hoffman
źródło
11
W rzeczywistości ładowanie strony nie ma nic wspólnego z przeglądarką , ale raczej, że serwer ignoruje dodatkowe ukośniki. Trwało to długo, więc zobacz odpowiedź, którą opublikowałem.
josh3736
33

Jak wspomniano w @RandomBen , podwójne cięcie jest najprawdopodobniej wynikiem błędu.

To, że strona się ładuje, nie ma nic wspólnego z przeglądarką , ale raczej, że serwer ignoruje dodatkowe ukośniki. Przeglądarka nie robi nic specjalnego z dodatkowymi ukośnikami w adresie URL, po prostu wysyła je wraz z żądaniem:

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

Wygląda na to, że obecne wersje Apache i IIS zignorują dodatkowe ukośniki podczas rozwiązywania ścieżki i zwrócą dokument, który zostałby zwrócony, gdyby adres URL nie zawierał dodatkowych ukośników. Jednak przeglądarki (testowałem IE 8 i Chrome 9) są mylone przez względne adresy URL (zawierające komponenty ścieżki nadrzędnej) zasobów na stronie, co daje złe wyniki. Na przykład jeśli strona ma:

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

Po załadowaniu strony /a/b/c/przeglądarka zażąda /a/style.css. Ale jeśli - z jakiegokolwiek powodu - /a/b//c/zostanie zażądany (a serwer zignoruje dodatkowy ukośnik), przeglądarka skończy z żądaniem /a/b/style.css, które nie będzie istnieć. Ups, strona wygląda brzydko.

(To oczywiście nie nastąpi, jeśli adres URL nie zawiera komponentu ścieżki nadrzędnej ( ..) lub jest bezwzględny).

To jest moja opinia, że Apache i IIS (i prawdopodobnie innych) działają nieprawidłowo , jak /a/b/c/i /a/b//c/technicznie reprezentują dwa różne zasoby. Według RFC 2396 każdy ukośnik jest znaczący:

  path          = [ abs_path | opaque_part ]

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

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

Tak więc /a/b/c/składa się z trzech segmentów: „a”, „b” i „c”; /a/b//c/właściwie składa się z czterech: „a”, „b”, „” (pusty ciąg) i „c”. To, czy pusty ciąg znaków jest poprawnym katalogiem systemu plików, jest szczegółem platformy serwera. (I logicznie oznacza to, że przeglądarki faktycznie działają poprawnie podczas analizowania względnych adresów URL ze składnikami ścieżki nadrzędnej - w moim przykładzie przechodzą one powyżej katalogu „c” i katalogu „”, pozostawiając nam żądanie style.cssz „b”.)

Jeśli używasz Apache z mod_rewrite, istnieje dość prosta poprawka :

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

Spowoduje to 301 Moved Permanentlyprzekierowanie HTTP, dzięki czemu wszelkie podwójne ukośniki zostaną usunięte z adresu URL.

josh3736
źródło
2
Czy nie byłoby lepiej, aby twoje mod_rewriterozwiązanie uwzględniało także 3, 4, ... ukośniki? Coś w stylu /{2,}? (Zakładając, że Apache zezwala na tego rodzaju kwantyfikator, nie znam go zbyt dobrze)
Ward Muylaert
+1 - Dzięki za dodatkowe informacje. Nie myślałem o tym w ten sposób!
Ben Hoffman,
3
To nie jest niepoprawne zachowanie: a/bi a//brzeczywiście są dwie odrębne ścieżki URL, ale nic nie zabrania serwer z powrotem ten sam zasób dla obu z nich, jeśli chce. Zgadzam się jednak z tobą, że w praktyce zwrócenie przekierowania 301 wydaje się bardziej przydatne.
Ilmari Karonen,
4
@IlmariKaronen: Jest to absolutnie niepoprawne zachowanie, ponieważ (1) to zachowanie automatycznie tworzy nieskończoną liczbę potencjalnych duplikatów odniesień do pojedynczego zasobu (który, jeśli nie jest sprzeczny z literą jakiejkolwiek specyfikacji, z pewnością narusza ducha), i bardziej praktycznie (2) „łamie” obsługę ścieżek względnych w przeglądarkach, które poprawnie liczą pusty ciąg znaków a//bjako katalog (patrz przykład arkusza stylów powyżej).
josh3736
1
... i tak, bym twierdzą, że RFC 2396 nie zabraniają serwer z powrotem ten sam zasób przez Auto-zwijanie ukośniki ponieważ spec mówi każdy ukośnik jest znacząca. Automatyczne ignorowanie kolejnych ukośników stanowi naruszenie tej specyfikacji. (Jest jedna rzecz, jeśli ktoś zaprogramować ich serwer, aby to zrobić, nawet jeśli byłoby to głupie Jednak serwery robi to domyślnie. Jest nieprawidłowe.)
josh3736
4

Podwójny ukośnik ma znaczenie, gdy jest używany w adresach URL zasobów. Na przykład, gdy jest użytkownikiem CSS dla adresu URL obrazu tła:

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

Oznacza to, że obraz tła pobiera się z innej domeny niż domena bieżącej strony internetowej. Innymi słowy, http://można go zapisać tak, jak w //przypadku użycia go w adresach URL zasobów.

Ale ten podwójny ukośnik między adresami URL (np . /a//b/c/d.htm:) nie ma żadnego znaczenia.

Alan Joseph
źródło
cóż, to nie jest cała prawda. Podwójny ukośnik jest stosowany, gdy trzeba uniknąć problemu z mieszaną treścią, dlatego gdy strona jest ładowana z http, doublebleslash rozwija się do http, gdy strona jest ładowana z https, doublebleslash jest rozwijany do https.
andrej
2

Jak wspomniano, niektóre serwery są skonfigurowane tak, aby ignorować podwójny ukośnik w ścieżce adresu URL, ale statyczny hosting Amazon S3 nie. Jeśli chcesz je obsłużyć / zignorować, możesz użyć Reguł przekierowania w panelu właściwości.

Jeśli chcesz zignorować podwójny ukośnik następujący po nazwie domeny, możesz użyć czegoś takiego:

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

Prawdopodobnie możesz je również znaleźć i wymienić na cały, ale to mi wystarczyło.

orlade
źródło