Fragment d'URL et redirections 302

136

Il est bien connu que le fragment d'URL (la partie après le #) n'est pas envoyé au serveur.

Je me demande cependant comment les fragments fonctionnent lorsqu'une redirection de serveur (via le statut HTTP 302 et l'en- Location:tête) est impliquée.

Ma question est vraiment double:

  1. Si l'URL d'origine avait un fragment ( /original.php#foo) et qu'une redirection est effectuée /new.php, la partie fragment de l'URL d'origine est-elle simplement perdue? Ou est-il parfois appliqué à la nouvelle URL?
    La nouvelle URL sera-t-elle un jour /new.php#foodans ce cas?

  2. Quelle que soit l'URL d'origine, si le serveur redirige vers une nouvelle URL avec un fragment ( /new.php#foo), le fragment sera-t-il "honoré"? Ou est-ce que le serveur n'a vraiment aucune raison d'interférer avec le fragment - et le navigateur l'ignorera-t-il donc simplement en allant sur /new.php??

Levik
la source
1
Ici vous pouvez trouver les spécifications du W3C: w3.org/TR/cuap#uri clause 4.1. le fragment doit être conservé lors de la redirection.
Marcin

Réponses:

135

Mise à jour du 27 juin 2014 :

La RFC 7231, Hypertext Transfer Protocol (HTTP / 1.1): Semantics and Content , a été publiée en tant que STANDARD PROPOSÉ. Depuis le journal des modifications :

La syntaxe du champ d'en-tête Location a été modifiée pour autoriser toutes les références URI, y compris les références relatives et les fragments, ainsi que quelques clarifications quant au moment où l'utilisation de fragments ne serait pas appropriée. (Section 7.1.2)

Les points importants de la section 7.1.2. Lieu :

Si la valeur d'emplacement fournie dans une réponse 3xx (Redirection) n'a pas de composant de fragment, un agent utilisateur DOIT traiter la redirection comme si la valeur hérite du composant de fragment de la référence URI utilisée pour générer la cible de la demande (c'est-à-dire que la redirection hérite le fragment de la référence d'origine, le cas échéant).

Par exemple, une requête GET générée pour la référence URI " http://www.example.org/~tim " peut entraîner une réponse 303 (See Other) contenant le champ d'en-tête:

Location: /People.html#tim

ce qui suggère que l'agent utilisateur redirige vers " http://www.example.org/People.html#tim "

De même, une requête GET générée pour la référence URI " http://www.example.org/index.html#larry " peut entraîner une réponse 301 (Moved Permanently) contenant le champ d'en-tête:

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

ce qui suggère que l'agent utilisateur redirige vers " http://www.example.net/index.html#larry ", en conservant l'identifiant du fragment d'origine.

Cela devrait clairement répondre à vos questions.

Mettre à jour END

il s'agit d'un problème ouvert (non spécifié) avec la spécification HTTP actuelle . il est abordé dans 2 numéros du groupe de travail IETF httpbis :

# 6 autorise les fragments dans l'en- Locationtête. # 43 dit ceci:

Je viens de tester cela avec différents navigateurs.

  • Firefox et Safari utilisent le fragment dans l'en-tête d'emplacement.
  • Opera utilise le fragment de l'URI source, lorsqu'il est présent, sinon le fragment de l'emplacement de redirection
  • IE (8) ignore le fragment dans l'URI de l'emplacement, donc utilisera le fragment de l'URI source, lorsqu'il est présent

Proposition:

"Remarque: le comportement lorsque les identifiants de fragment de l'URI d'origine et de la redirection doivent être combinés n'est pas défini; les agents utilisateurs actuels diffèrent en effet sur le fragment qui prime."

[...]

Il semble que IE8 n'utiliser le fragment idenfitier de (I saw comportement pourrait se limiter à localhost).Location

Ainsi, nous semblons avoir un comportement cohérent pour Safari / IE / Firefox / Chrome (juste testé), en ce que le fragment de l'en-tête Location est utilisé, quel que soit l'URI d'origine.

Je modifie donc ma proposition pour documenter cela comme un comportement attendu.

cela conduit à la réponse la plus compatible avec les navigateurs et la plus pérenne (car ce problème finira par être normalisé) à votre question:

R: les fragments des URL d'origine sont supprimés.

B: les fragments de l'en- Locationtête sont honorés.

hache.
la source
1
J'avais oublié certaines règles de "réécriture" que j'avais définies dans les serveurs HTTP, qui étaient probablement implémentées en tant que redirection 301. En conséquence, IE a continué à perdre l'identifiant de fragment car lorsque vous avez plusieurs redirections, les fragments définis par la première redirection deviennent une partie de l' URI source dans la seconde.
Eugene Yokota le
l'opéra 12.12 honore le fragment dans l'en-tête d'emplacement lorsqu'il est présent.
chèvre
4
Sur les versions actuelles de Chrome et Firefox: A n'est pas vrai. Sur la version actuelle de Firefox: B n'est pas vrai. Pour le moment, si vous devez utiliser des hachages (par exemple, en utilisant le routage de Backbone), il semble que la redirection basée sur JavaScript soit votre seule vraie option.
a.real.human.be du
Le bloc cité semble se contredire. D'abord, il dit "IE (8) ignore le fragment dans l'URI d'emplacement, utilisera donc le fragment de l'URI source, lorsqu'il est présent", puis plus tard il dit "Il semble qu'IE8 utilise l'identificateur de fragment d'emplacement". Le premier fait-il référence à quelque chose de différent du second?
davidtbernal
B n'est pas vrai pour Chome 45.0.2454.85. B est vrai pour Firefox 40.0.3.
Jingguo Yao
44

Safari 5 et IE9 et inférieurs suppriment le fragment de l'URI d'origine si une redirection HTTP / 3xx se produit. Si l'en-tête Location de la réponse spécifie un fragment, il est utilisé.

IE10 +, Chrome 11+, Firefox 4+ et Opera "rattacheront" tous le fragment de l'URI d'origine après avoir suivi une redirection 3xx.

Page de test: http://www.webdbg.com/test/redir/fragment/ .

Pour plus d'informations sur ce problème, consultez http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx

EricLaw
la source
2
En fait, IE10 se comporte toujours différemment des dernières versions de Firefox et Chrome. Il semble conserver le fragment de l'URL source en cas de simple redirection. Et si la redirection Locationcontient un fragment, elle le conservera correctement. Mais si une redirection Locationavec un fragment passe par une autre redirection 3xx, elle ignorera inexplicablement le fragment de la première redirection, ce qui n'est pas cohérent avec les 2 comportements précédents. Chrome et Firefox le préservent systématiquement.
odony
J'ai confirmé que vous avez raison. Voir le lien du test final sur cette page: webdbg.com/test/redir/fragment
EricLaw
11

Juste pour vous le faire savoir, vous trouverez ici les spécifications appropriées. par w3c définissant comment tout le monde doit se comporter: http://www.w3.org/TR/cuap#uri - clause 4.1 - voir ci-dessous:

Lorsqu'une ressource (URI1) a été déplacée, une redirection HTTP peut indiquer son nouvel emplacement (URI2).

Si URI1 a un identificateur de fragment #frag, alors la nouvelle cible que l'agent utilisateur devrait essayer d'atteindre serait URI2 # frag. Si URI2 a déjà un identifiant de fragment, alors #frag ne doit pas être ajouté et la nouvelle cible est URI2.

Faux: la plupart des agents utilisateurs actuels implémentent des redirections HTTP mais n'ajoutent pas l'identifiant de fragment au nouvel URI, ce qui confond généralement l'utilisateur car il se retrouve avec la mauvaise ressource.

Références:

Les redirections HTTP sont décrites dans la section 10.3 de la spécification HTTP / 1.1 [RFC2616]. Le comportement requis est décrit en détail dans "Gestion des identifiants de fragments dans les URL redirigées" [RURL]. Le terme «Persistent Uniform Resource Locator (PURL)» désigne une URL (un cas particulier d'URI) qui pointe vers une autre via une redirection HTTP. Pour plus d'informations, reportez-vous à «Localisateurs de ressources uniformes persistantes» [PURL]. Exemple:

Supposons qu'un utilisateur demande la ressource à http://www.w3.org/TR/WD-ruby/#changes et que le serveur redirige l'agent utilisateur vers http://www.w3.org/TR/ruby/ . Avant de récupérer ce dernier URI, le navigateur doit y ajouter l'identifiant de fragment #changes: http://www.w3.org/TR/ruby/#changes .

Marcin
la source
0

Publication d'un problème similaire avec la solution que j'ai rencontrée.

J'espère que cela aidera quelqu'un avec l'exigence similaire de preserving hash in IEpour 302 redirections.

Ajouter des parties essentielles de la réponse au lieu des liens seuls

Nous utilisons l' SiteMinderauthentification dans notre application.

Je me suis dit que , après une authentification réussie, SiteMinderest fait 302 redirectionà la page d'application demandée d'utilisateur à l'aide sous forme de connexion variable cachéevalue (où il stocke des données d' URL demandé /myapp/- without hash fragmentcar il ne sera pas envoyé au serveur) avec un nom semblable à redirect. Exemple de formulaire ci-dessous

Exemple de formulaire de connexion

Étant donné que la valeur de laredirect variable cachée contient uniquement sans fragment de hachage et qu'il s'agit d'une redirection 302, le fragment de hachage est automatiquement supprimé par IE avant même d'arriver à notre application et quelles que soient les solutions que nous essayons dans notre code d'application, elles ne fonctionnent pas./myapp/

IE redirige /myapp/uniquement vers et atterrit sur la page d'accueil par défaut de notre application https://ourapp.com/myapp/#/home.

J'ai perdu presque une journée pour comprendre ce comportement.

La solution est:

Ont changé la valeur de la variable cachée ( ) du formulaire de connexion pour contenir le fragment de hachage en l'ajoutant avec la valeur existante. Similaire au code ci-dessousredirectwindow.location.hash

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

Après ce changement, la redirectvariable masquée stocke la valeur de l'URL demandée par l'utilisateur en tant que /myapp/#/pending/requestset la SiteMinderredirige vers /myapp/#/pending/requestsdans IE.

La solution ci-dessus fonctionne correctement dans les trois navigateurs Chrome, Firefox and IE.

Merci à @AlexFord pour l' explication détaillée et la solution à ce problème.

Prathap Reddy
la source