Fragment adresu URL i przekierowania 302

136

Powszechnie wiadomo, że fragment adresu URL (część po znaku #) nie jest wysyłany na serwer.

Zastanawiam się jednak, jak działają fragmenty, gdy w grę wchodzi przekierowanie serwera (przez stan HTTP 302 i Location:nagłówek).

Moje pytanie jest naprawdę dwojakie:

  1. Jeśli pierwotny adres URL miał fragment ( /original.php#foo) i następuje przekierowanie /new.php, czy fragment oryginalnego adresu URL po prostu się zgubi? A może czasami jest stosowany do nowego adresu URL?
    Czy nowy adres URL będzie kiedykolwiek /new.php#foow takim przypadku?

  2. Niezależnie od oryginalnego adresu URL, jeśli serwer przekierowuje do nowego adresu URL z fragmentem ( /new.php#foo), czy fragment zostanie „uhonorowany”? A może serwer naprawdę nie ma żadnego interesu w ingerowaniu w ten fragment - i czy w związku z tym przeglądarka zignoruje go, po prostu przechodząc do /new.php??

levik
źródło
1
Tutaj możesz znaleźć specyfikację W3C: w3.org/TR/cuap#uri klauzula 4.1. fragment należy zachować przy przekierowaniu.
Marcin

Odpowiedzi:

135

Aktualizacja 2014-czerwiec-27 :

RFC 7231, Hypertext Transfer Protocol (HTTP / 1.1): Semantics and Content , został opublikowany jako PROPONOWANY STANDARD. Z Changelog :

Składnia pola nagłówka Location została zmieniona, aby umożliwić wszystkie odwołania URI, w tym odniesienia względne i fragmenty, wraz z pewnymi wyjaśnieniami, kiedy użycie fragmentów byłoby niewłaściwe. (Punkt 7.1.2)

Ważne punkty z sekcji 7.1.2. Lokalizacja :

Jeśli wartość lokalizacji podana w odpowiedzi 3xx (przekierowanie) nie ma składnika fragmentu, agent użytkownika MUSI przetworzyć przekierowanie tak, jakby wartość dziedziczyła składnik fragmentu odwołania URI używanego do wygenerowania celu żądania (tj. Przekierowanie dziedziczy fragment oryginalnego odniesienia, jeśli istnieje).

Na przykład żądanie GET wygenerowane dla odwołania URI „ http://www.example.org/~tim ” może skutkować odpowiedzią 303 (Zobacz inne) zawierającą pole nagłówka:

Location: /People.html#tim

co sugeruje, że klient użytkownika przekierowuje do „ http://www.example.org/People.html#tim

Podobnie żądanie GET wygenerowane dla odwołania URI „ http://www.example.org/index.html#larry ” może skutkować odpowiedzią 301 (przeniesioną na stałe) zawierającą pole nagłówka:

Location: http://www.example.net/index.html

co sugeruje, że program użytkownika przekierowuje do „ http://www.example.net/index.html#larry ”, zachowując oryginalny identyfikator fragmentu.

Powinno to jasno odpowiedzieć na Twoje pytania.

Zaktualizuj END

jest to otwarty (nieokreślony) problem z aktualną specyfikacją HTTP . omówiono go w 2 wydaniach grupy roboczej IETF httpbis :

# 6 zezwala na fragmenty w Locationnagłówku. # 43 mówi tak:

Właśnie przetestowałem to w różnych przeglądarkach.

  • Firefox i Safari używają fragmentu w nagłówku lokalizacji.
  • Opera używa fragmentu ze źródłowego URI, jeśli jest obecny, w przeciwnym razie fragmentu z lokalizacji przekierowania
  • IE (8) ignoruje fragment w identyfikatorze URI lokalizacji, więc użyje fragmentu ze źródłowego URI, jeśli jest obecny

Wniosek:

„Uwaga: zachowanie, gdy identyfikatory fragmentów z oryginalnego URI i przekierowania muszą zostać połączone, jest nieokreślone; obecne programy klienckie rzeczywiście różnią się tym, który fragment ma pierwszeństwo”.

[…]

Wydaje się, że IE8 nie używać idenfitier fragment Location(zachowanie widziałem może być ograniczona do localhost).

Dlatego wydaje się, że mamy spójne zachowanie dla Safari / IE / Firefox / Chrome (właśnie przetestowane), ponieważ fragment z nagłówka Location jest używany, bez względu na oryginalny identyfikator URI.

Dlatego zmieniam swoją propozycję, aby udokumentować to zgodnie z oczekiwaniami.

Prowadzi to do najbardziej kompatybilnej z przeglądarkami i przyszłościowej (ponieważ ten problem ostatecznie zostanie ujednolicony) odpowiedzi na Twoje pytanie:

O: fragmenty z oryginalnych adresów URL są odrzucane.

B: fragmenty Locationnagłówka są honorowane.

topór.
źródło
1
Zapomniałem o niektórych regułach „przepisywania”, które ustawiłem na serwerach HTTP, które prawdopodobnie zostały zaimplementowane jako przekierowanie 301. W rezultacie IE tracił identyfikator fragmentu, ponieważ w przypadku wielu przekierowań fragmenty ustawione przez pierwsze przekierowanie stają się częścią źródłowego identyfikatora URI w drugim.
Eugene Yokota,
opera 12.12 honoruje fragment nagłówka lokalizacji, jeśli jest obecny.
koza
4
W obecnych wersjach przeglądarki Chrome i Firefox: A nie jest prawdą. W aktualnej wersji przeglądarki Firefox: B nie jest prawdą. W tej chwili, jeśli musisz używać skrótów (np. Używając routingu Backbone), wydaje się, że przekierowanie oparte na javascript jest jedyną realną opcją.
Prawdziwy.ludzki.
Cytowany blok wydaje się sobie zaprzeczać. Najpierw mówi „IE (8) ignoruje fragment w lokalizacji URI, więc użyje fragmentu ze źródłowego URI, jeśli jest obecny”, a później mówi „Wygląda na to, że IE8 używa identyfikatora fragmentu z lokalizacji”. Czy pierwsza odnosi się do czegoś innego niż druga?
davidtbernal
B nie jest prawdą dla Chome 45.0.2454.85. B jest prawdziwe dla przeglądarki Firefox 40.0.3.
Jingguo Yao
44

Safari 5 i IE9 i starsze usuwają fragment oryginalnego identyfikatora URI, jeśli wystąpi przekierowanie HTTP / 3xx. Jeśli nagłówek Location odpowiedzi określa fragment, jest on używany.

IE10 +, Chrome 11+, Firefox 4+ i Opera wszystkie „ponownie dołączą” oryginalny fragment URI po wykonaniu przekierowania 3xx.

Strona testowa: http://www.webdbg.com/test/redir/fragment/ .

Zobacz dalsze omówienie tego problemu pod adresem http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx

EricLaw
źródło
2
W rzeczywistości IE10 nadal zachowuje się inaczej niż najnowsze wersje przeglądarek Firefox i Chrome. Wydaje się, że zachowuje fragment ze źródłowego adresu URL w przypadku prostego przekierowania. A jeśli przekierowanie Locationzawiera fragment, zachowa go poprawnie. Ale jeśli przekierowanie Locationz fragmentem przechodzi przez inne przekierowanie 3xx, w niewytłumaczalny sposób zignoruje fragment z pierwszego przekierowania, co nie jest zgodne z 2 poprzednimi zachowaniami. Chrome i Firefox konsekwentnie go zachowują.
odony
Potwierdziłem, że masz rację. Zobacz końcowy link do testu na tej stronie: webdbg.com/test/redir/fragment
EricLaw
11

Abyś wiedział, tutaj znajdziesz odpowiednią specyfikację. przez w3c definiujące, jak wszyscy powinni się zachowywać: http://www.w3.org/TR/cuap#uri - punkt 4.1 - patrz poniżej:

Gdy zasób (URI1) zostanie przeniesiony, przekierowanie HTTP może wskazać jego nową lokalizację (URI2).

Jeśli URI1 ma identyfikator fragmentu #frag, to nowy cel, do którego agent użytkownika powinien próbować dotrzeć, to URI2 # frag. Jeśli URI2 ma już identyfikator fragmentu, nie można dodawać #frag, a nowym celem jest URI2.

Źle: Większość obecnych programów klienckich implementuje przekierowania HTTP, ale nie dodaje identyfikatora fragmentu do nowego URI, co generalnie dezorientuje użytkownika, ponieważ kończy z niewłaściwym zasobem.

Bibliografia:

Przekierowania HTTP są opisane w sekcji 10.3 specyfikacji HTTP / 1.1 [RFC2616]. Wymagane zachowanie opisano szczegółowo w sekcji „Obsługa identyfikatorów fragmentów w przekierowanych adresach URL” [RURL]. Termin „Persistent Uniform Resource Locator (PURL)” oznacza adres URL (specjalny przypadek identyfikatora URI), który wskazuje inny adres URL za pośrednictwem przekierowania HTTP. Aby uzyskać więcej informacji, zobacz „Trwałe jednolite lokalizatory zasobów” [PURL]. Przykład:

Załóżmy, że użytkownik żąda zasobu pod adresem http://www.w3.org/TR/WD-ruby/#changes, a serwer przekierowuje agenta użytkownika na http://www.w3.org/TR/ruby/ . Przed pobraniem tego ostatniego URI przeglądarka powinna dołączyć do niego identyfikator fragmentu #changes: http://www.w3.org/TR/ruby/#changes .

Marcin
źródło
0

Publikowanie podobnego problemu z rozwiązaniem, które napotkałem.

Mam nadzieję, że pomoże to komuś z podobnym wymogiem preserving hash in IEprzekierowań 302.

Dodanie istotnych części odpowiedzi zamiast samych linków

Używamy SiteMinderW naszej aplikacji uwierzytelnianie.

Doszedłem do wniosku, że po udanym uwierzytelnieniu, SiteMinderwykonuje 302 redirectionżądaną przez użytkownika stronę aplikacji za pomocą ukrytej zmiennej formularza logowaniavalue (gdzie przechowuje żądany przez użytkownika adres URL /myapp/- without hash fragmentponieważ nie zostanie wysłany na serwer) o nazwie podobnej do redirect. Przykładowy formularz poniżej

Przykładowy formularz logowania

Ponieważ redirectukryta wartość zmiennej zawiera tylko/myapp/ fragment z krzyżykiem i jest to przekierowanie 302, fragment skrótu jest automatycznie usuwany przez IE nawet przed wejściem do naszej aplikacji i niezależnie od rozwiązań, które próbujemy w naszym kodzie aplikacji, nie działają.

IE przekierowuje do /myapp/ tylko i ląduje na domyślnej stronie głównej naszej aplikacjihttps://ourapp.com/myapp/#/home .

Zmarnowałem prawie dzień, aby zrozumieć to zachowanie.

Rozwiązaniem jest:

Zmieniliśmy formularz logowania zmienne ukryte ( redirect) wartość utrzymać ten fragment hash dołączając window.location.hashwraz z istniejącą wartość. Podobny do poniższego kodu

$(function () {
  var $redirect = $('input[name="redirect"]');
  $redirect.val($redirect.val() + window.location.hash);
});

Po tej zmianie redirectukryta zmienna przechowuje żądaną przez użytkownika wartość adresu URL jako /myapp/#/pending/requestsi SiteMinderprzekierowuje ją /myapp/#/pending/requestsw IE.

Powyższe rozwiązanie działa poprawnie we wszystkich trzech przeglądarkach Chrome, Firefox and IE.

Dzięki @AlexFord za szczegółowe wyjaśnienie i rozwiązanie tego problemu.

Prathap Reddy
źródło