Frammento URL e 302 reindirizzamenti


136

È noto che il frammento di URL (la parte dopo il #) non viene inviato al server.

Mi chiedo però come funzionano i frammenti quando Location:è coinvolto un reindirizzamento del server (tramite lo stato HTTP 302 e l' intestazione).

La mia domanda è davvero duplice:

  1. Se l'URL originale aveva un frammento ( /original.php#foo) e viene effettuato un reindirizzamento /new.php, la parte del frammento dell'URL originale si perde semplicemente? O a volte viene applicato al nuovo URL?
    Il nuovo URL sarà mai /new.php#fooin questo caso?

  2. Indipendentemente dall'URL originale, se il server reindirizza a un nuovo URL con un frammento ( /new.php#foo), il frammento verrà "onorato"? O il server non ha davvero alcuna attività che interferisca con il frammento - e quindi il browser lo ignorerà semplicemente andando /new.php??


1
Qui puoi trovare le specifiche di W3C: w3.org/TR/cuap#uri clausola 4.1. il frammento deve essere conservato al reindirizzamento.
Marcin,

Risposte:


135

Aggiornamento 2014-giu-27 :

RFC 7231, Hypertext Transfer Protocol (HTTP / 1.1): Semantica e contenuto , è stato pubblicato come PROPOSED STANDARD. Dal log delle modifiche :

La sintassi del campo dell'intestazione Posizione è stata modificata per consentire tutti i riferimenti URI, inclusi riferimenti e frammenti relativi, insieme ad alcuni chiarimenti su quando l'uso dei frammenti non sarebbe appropriato. (Sezione 7.1.2)

I punti importanti della Sezione 7.1.2. Posizione :

Se il valore Posizione fornito in una risposta 3xx (reindirizzamento) non ha un componente di frammento, un agente utente DEVE elaborare il reindirizzamento come se il valore erediti il ​​componente di frammento del riferimento URI utilizzato per generare la destinazione richiesta (ovvero, il reindirizzamento eredita il frammento del riferimento originale, se presente).

Ad esempio, una richiesta GET generata per il riferimento URI " http://www.example.org/~tim " potrebbe comportare una risposta 303 (Vedi altro) contenente il campo di intestazione:

Location: /People.html#tim

che suggerisce che l'agente utente reindirizza a " http://www.example.org/People.html#tim "

Allo stesso modo, una richiesta GET generata per il riferimento URI " http://www.example.org/index.html#larry " potrebbe comportare una risposta 301 (spostata in modo permanente) contenente il campo di intestazione:

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

che suggerisce che l'agente utente reindirizza a " http://www.example.net/index.html#larry ", preservando l'identificatore del frammento originale.

Questo dovrebbe rispondere chiaramente alle tue domande.

Aggiorna END

questo è un problema aperto (non specificato) con la specifica HTTP corrente . è affrontato in 2 numeri del gruppo di lavoro httpbis IETF :

# 6 consente frammenti Locationnell'intestazione. # 43 dice questo:

Ho appena provato questo con vari browser.

  • Firefox e Safari utilizzano il frammento nell'intestazione della posizione.
  • Opera utilizza il frammento dall'URI di origine, quando presente, altrimenti il ​​frammento dalla posizione di reindirizzamento
  • IE (8) ignora il frammento nell'URI di posizione, quindi utilizzerà il frammento dall'URI di origine, quando presente

Proposta:

"Nota: il comportamento in cui gli identificatori di frammento dall'URI originale e il reindirizzamento devono essere combinati non è definito; gli attuali agenti utente differiscono effettivamente su quale frammento abbia la precedenza."

[...]

Sembra che IE8 non utilizzare l'idenfitier frammento Location(l'ho visto comportamento potrebbe essere limitata a localhost).

Pertanto, sembra che abbiamo un comportamento coerente per Safari / IE / Firefox / Chrome (appena testato), in quanto viene utilizzato il frammento dell'intestazione Posizione, indipendentemente dall'URI originale.

Pertanto cambiare la mia proposta di documento che come comportamento previsto.

questo porta alla risposta più compatibile con il browser e futura (perché questo problema alla fine diventerà standardizzato) alla tua domanda:

A: i frammenti degli URL originali vengono scartati.

B: i frammenti Locationdell'intestazione sono onorati.


1
Avevo dimenticato alcune regole di "riscrittura" che ho impostato nei server HTTP, che probabilmente sono state implementate come reindirizzamento 301. Di conseguenza IE ha continuato a perdere l'identificatore di frammento perché quando si hanno reindirizzamenti multipli, i frammenti impostati dal primo reindirizzamento diventano parte dell'URI di origine nel secondo.
Eugene Yokota,

opera 12.12 onora il frammento nell'intestazione della posizione quando presente.
capra,

4
Sulle versioni attuali di Chrome e Firefox: A non è vero. Nella versione corrente di Firefox: B non è vero. Al momento, se devi usare gli hash (ad es. Usando il routing di Backbone) sembra che il reindirizzamento basato su javascript sia la tua unica vera opzione.
a.real.human.being

Il blocco citato sembra contraddirsi. Prima dice "IE (8) ignora il frammento nell'URI della posizione, quindi utilizzerà il frammento dall'URI di origine, quando presente", quindi in seguito dice "Sembra che IE8 utilizzi l'identificatore di frammento dalla posizione". Il primo si riferisce a qualcosa di diverso dal secondo?
davidtbernal,

B non è vero per Chome 45.0.2454.85. B è vero per Firefox 40.0.3.
Jingguo Yao,

44

Safari 5 e IE9 e versioni precedenti rilasciano il frammento dell'URI originale se si verifica un reindirizzamento HTTP / 3xx. Se l'intestazione Location sulla risposta specifica un frammento, viene utilizzato.

IE10 +, Chrome 11+, Firefox 4+ e Opera "ricollegheranno" il frammento dell'URI originale dopo aver seguito un reindirizzamento 3xx.

Pagina di prova: http://www.webdbg.com/test/redir/fragment/ .

Vedi ulteriori discussioni su questo problema su http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx


2
In realtà IE10 si comporta ancora diversamente dalle ultime versioni di Firefox e Chrome. Sembra preservare il frammento dall'URL di origine in caso di un semplice reindirizzamento. E se il reindirizzamento Locationcontiene un frammento, lo manterrà correttamente. Ma se un reindirizzamento Locationcon un frammento passa attraverso un altro reindirizzamento 3xx, ignorerà inspiegabilmente il frammento dal primo reindirizzamento, che non è coerente con i 2 comportamenti precedenti. Chrome e Firefox lo preservano costantemente.
odony,

Ho confermato che hai ragione. Vedi il link del test finale in questa pagina: webdbg.com/test/redir/fragment
EricLaw

11

Solo per farti sapere, qui puoi trovare le specifiche adeguate. definendo come dovrebbero comportarsi tutti: http://www.w3.org/TR/cuap#uri - clausola 4.1 - vedi sotto:

Quando una risorsa (URI1) viene spostata, un reindirizzamento HTTP può indicare la sua nuova posizione (URI2).

Se URI1 ha un identificatore di frammento #frag, la nuova destinazione che l'agente utente dovrebbe tentare di raggiungere sarebbe URI2 # frag. Se URI2 ha già un identificatore di frammento, allora #frag non deve essere aggiunto e la nuova destinazione è URI2.

Sbagliato: la maggior parte dei programmi utente attuali implementano reindirizzamenti HTTP ma non aggiungono l'identificatore di frammento al nuovo URI, che generalmente confonde l'utente perché finisce con la risorsa sbagliata.

Riferimenti:

I reindirizzamenti HTTP sono descritti nella sezione 10.3 della specifica HTTP / 1.1 [RFC2616]. Il comportamento richiesto è descritto in dettaglio in "Gestione degli identificativi di frammento negli URL reindirizzati" [RURL]. Il termine "Persistent Uniform Resource Locator (PURL)" indica un URL (un caso speciale di un URI) che punta a un altro tramite un reindirizzamento HTTP. Per ulteriori informazioni, consultare "Individuatori di risorse uniformi persistenti" [PURL]. Esempio:

Supponiamo che un utente richieda la risorsa su http://www.w3.org/TR/WD-ruby/#changes e che il server reindirizzi l'agente utente su http://www.w3.org/TR/ruby/ . Prima di recuperare quest'ultimo URI, il browser dovrebbe aggiungere l'identificatore del frammento #changes ad esso: http://www.w3.org/TR/ruby/#changes .


0

Pubblicare problemi simili con la soluzione da me affrontata.

Spero che aiuti a qualcuno con il requisito simile preserving hash in IEper 302 reindirizzamenti.

Aggiunta di parti essenziali della risposta anziché dei soli collegamenti

Usiamo l' SiteMinderautenticazione nella nostra applicazione.

Ho scoperto che, dopo aver eseguito correttamente l'autenticazione, SiteMindersta eseguendo 302 redirectionla pagina dell'applicazione richiesta dall'utente utilizzando la variabile nascosta del modulo di accessovalue (dove memorizza l'URL richiesto dall'utente /myapp/, without hash fragmentpoiché non verrà inviato al server) con un nome simile a redirect. Modulo di esempio di seguito

Modulo di login di esempio

Poiché il valore dellaredirect variabile nascosta contiene solo senza frammento di hash ed è un reindirizzamento 302, il frammento di hash viene rimosso automaticamente da IE anche prima di arrivare alla nostra applicazione e qualunque siano le soluzioni che stiamo provando nel nostro codice dell'applicazione non sta funzionando./myapp/

IE reindirizza /myapp/solo a e sta atterrando sulla home page predefinita della nostra app https://ourapp.com/myapp/#/home.

Ho perso quasi un giorno per capire questo comportamento.

La soluzione è:

Ho modificato il valore della variabile nascosta ( ) del modulo di accesso per contenere il frammento di hash aggiungendo un valore esistente. Simile al codice qui sottoredirectwindow.location.hash

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

Dopo questa modifica, la redirectvariabile nascosta memorizza il valore URL richiesto dall'utente come /myapp/#/pending/requestse SiteMinderlo reindirizza a /myapp/#/pending/requestsIE.

La soluzione sopra funziona perfettamente in tutti e tre i browser Chrome, Firefox and IE.

Grazie a @AlexFord per la spiegazione dettagliata e la soluzione a questo problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.