Fragmento de URL y redireccionamientos 302

136

Es bien sabido que el fragmento de URL (la parte posterior a #) no se envía al servidor.

Sin embargo, me pregunto cómo funcionan los fragmentos cuando Location:está involucrado un redireccionamiento del servidor (a través del estado 302 de HTTP y el encabezado).

Mi pregunta es realmente doble:

  1. Si la URL original tenía un fragmento ( /original.php#foo), y se realiza una redirección /new.php, ¿se pierde la parte del fragmento de la URL original? ¿O a veces se aplica a la nueva URL?
    ¿La nueva URL alguna vez estará /new.php#fooen este caso?

  2. Independientemente de la URL original, si el servidor redirige a una nueva URL con un fragmento ( /new.php#foo), ¿se "honrará" el fragmento? ¿O el servidor realmente no tiene ningún problema para interferir con el fragmento? ¿El navegador lo ignorará simplemente yendo a /new.php?

levik
fuente
1
Aquí puede encontrar especificaciones de W3C: w3.org/TR/cuap#uri cláusula 4.1. El fragmento debe conservarse en la redirección.
Marcin

Respuestas:

135

Actualización 2014-junio-27 :

RFC 7231, Protocolo de transferencia de hipertexto (HTTP / 1.1): semántica y contenido , se ha publicado como una NORMA PROPUESTA. Desde el registro de cambios :

La sintaxis del campo del encabezado Ubicación se ha cambiado para permitir todas las referencias de URI, incluidas las referencias y fragmentos relativos, junto con algunas aclaraciones sobre cuándo no sería apropiado el uso de fragmentos. (Sección 7.1.2)

Los puntos importantes de la Sección 7.1.2. Ubicación :

Si el valor de ubicación proporcionado en una respuesta 3xx (redirección) no tiene un componente de fragmento, un agente de usuario DEBE procesar la redirección como si el valor heredara el componente de fragmento de la referencia URI utilizada para generar el objetivo de solicitud (es decir, la redirección hereda el fragmento de la referencia original, si existe).

Por ejemplo, una solicitud GET generada para la referencia de URI " http://www.example.org/~tim " podría dar como resultado una respuesta 303 (Ver otra) que contiene el campo de encabezado:

Location: /People.html#tim

lo que sugiere que el agente de usuario redirija a " http://www.example.org/People.html#tim "

Del mismo modo, una solicitud GET generada para la referencia de URI " http://www.example.org/index.html#larry " podría dar como resultado una respuesta 301 (movida permanentemente) que contiene el campo de encabezado:

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

lo que sugiere que el agente de usuario redirija a " http://www.example.net/index.html#larry ", conservando el identificador de fragmento original.

Esto debería responder claramente a sus preguntas.

Actualizar FIN

Este es un problema abierto (no especificado) con la especificación HTTP actual . se aborda en 2 números del grupo de trabajo httpbis de IETF :

# 6 permite fragmentos en el Locationencabezado. # 43 dice esto:

Acabo de probar esto con varios navegadores.

  • Firefox y Safari usan el fragmento en el encabezado de ubicación.
  • Opera utiliza el fragmento del URI de origen, cuando está presente, de lo contrario, el fragmento de la ubicación de redireccionamiento
  • IE (8) ignora el fragmento en el URI de ubicación, por lo tanto, usará el fragmento del URI de origen, cuando esté presente

Propuesta:

"Nota: el comportamiento cuando los identificadores de fragmentos del URI original y la redirección deben combinarse no está definido; los Agentes de usuario actuales de hecho difieren en qué fragmento tiene prioridad".

[...]

Parece que IE8 hace uso de la idenfitier fragmento de Location(la vi comportamiento podría estar limitada a localhost).

Por lo tanto, parece que tenemos un comportamiento consistente para Safari / IE / Firefox / Chrome (recién probado), ya que el fragmento del encabezado Location se usa, sin importar cuál sea el URI original.

Por lo tanto, cambio mi propuesta para documentar eso como comportamiento esperado.

Esto lleva a la respuesta más compatible con el navegador y a prueba de futuro (porque este problema finalmente se estandarizará) responde a su pregunta:

R: los fragmentos de las URL originales se descartan.

B: se respetan los fragmentos del Locationencabezado.

hacha.
fuente
1
Me había olvidado de algunas reglas de "reescritura" que establecí en los servidores HTTP, que probablemente se implementaron como redireccionamiento 301. Como consecuencia, IE siguió perdiendo el identificador de fragmento porque cuando tiene múltiples redirecciones, los fragmentos establecidos por la primera redirección se vuelven parte del URI de origen en la segunda.
Eugene Yokota
opera 12.12 honra el fragmento en el encabezado de ubicación cuando está presente.
cabra
44
En las versiones actuales de Chrome y Firefox: A no es cierto. En la versión actual de Firefox: B no es cierto. Por el momento, si tiene que usar hashes (por ejemplo, usando el enrutamiento de Backbone), parece que la redirección basada en JavaScript es su única opción real.
a.real.human.being
El bloque citado parece contradecirse. Primero dice "IE (8) ignora el fragmento en el URI de ubicación, por lo tanto usará el fragmento del URI de origen, cuando esté presente", luego dice "Parece que IE8 usa el identificador de fragmento de Ubicación". ¿El primero se refiere a algo diferente del segundo?
davidtbernal
B no es cierto para Chome 45.0.2454.85. B es cierto para Firefox 40.0.3.
Jingguo Yao
44

Safari 5 e IE9 y versiones posteriores sueltan el fragmento del URI original si se produce una redirección HTTP / 3xx. Si el encabezado Ubicación en la respuesta especifica un fragmento, se utiliza.

IE10 +, Chrome 11+, Firefox 4+ y Opera "volverán a unir" el fragmento del URI original después de seguir una redirección 3xx.

Página de prueba: http://www.webdbg.com/test/redir/fragment/ .

Consulte más información sobre este tema en http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx

EricLaw
fuente
2
En realidad, IE10 todavía se comporta de manera diferente a las últimas versiones de Firefox y Chrome. Parece preservar el fragmento de la URL de origen en caso de una simple redirección. Y si la redirección Locationcontiene un fragmento, lo mantendrá correctamente. Pero si un redireccionado Locationcon un fragmento pasa por otro redireccionamiento 3xx, ignorará inexplicablemente el fragmento de la primera redirección, lo que no es consistente con los 2 comportamientos anteriores. Chrome y Firefox lo conservan constantemente.
odony
He confirmado que tienes razón. Vea el enlace de prueba final en esta página: webdbg.com/test/redir/fragment
EricLaw
11

Solo para hacerle saber, aquí puede encontrar las especificaciones adecuadas. por w3c definiendo cómo deben comportarse todos: http://www.w3.org/TR/cuap#uri - cláusula 4.1 - ver abajo:

Cuando un recurso (URI1) se ha movido, una redirección HTTP puede indicar su nueva ubicación (URI2).

Si URI1 tiene un identificador de fragmento #frag, entonces el nuevo objetivo que el agente de usuario debería intentar alcanzar sería URI2 # frag. Si URI2 ya tiene un identificador de fragmento, no se debe agregar #frag y el nuevo objetivo es URI2.

Incorrecto: la mayoría de los agentes de usuario actuales implementan redirecciones HTTP, pero no agregan el identificador de fragmento al nuevo URI, lo que generalmente confunde al usuario porque termina con el recurso incorrecto.

Referencias

Las redirecciones HTTP se describen en la sección 10.3 de la especificación HTTP / 1.1 [RFC2616]. El comportamiento requerido se describe en detalle en "Manejo de identificadores de fragmentos en URL redirigidos" [RURL]. El término "Localizador uniforme de recursos persistentes (PURL)" designa una URL (un caso especial de un URI) que apunta a otra a través de una redirección HTTP. Para obtener más información, consulte "Localizadores uniformes de recursos persistentes" [PURL]. Ejemplo:

Suponga que un usuario solicita el recurso en http://www.w3.org/TR/WD-ruby/#changes y el servidor redirige al agente de usuario a http://www.w3.org/TR/ruby/ . Antes de buscar ese último URI, el navegador debe agregarle el identificador de fragmento #changes: http://www.w3.org/TR/ruby/#changes .

Marcin
fuente
0

Publicar un problema similar con la solución que enfrento.

Espero que ayude a alguien con el requisito similar de preserving hash in IEredireccionamientos 302.

Agregar partes esenciales de la respuesta en lugar de solo enlaces

Usamos SiteMinderautenticación en nuestra aplicación.

Me di cuenta de que, después de una autenticación exitosa, SiteMinderestá haciendo 302 redirectionla página de aplicación solicitada por el usuario mediante el uso de la variable oculta del formulario de inicio de sesiónvalue (donde almacena la URL solicitada por el usuario /myapp/, without hash fragmentya que no se enviará al servidor) con un nombre similar a redirect. Ejemplo de formulario a continuación

Formulario de inicio de sesión de muestra

Dado redirectque el valor de la variable oculta contiene solo /myapp/sin fragmento hash y es una redirección 302, IE elimina automáticamente el fragmento hash incluso antes de llegar a nuestra aplicación y las soluciones que estamos probando en nuestro código de aplicación no están funcionando.

IE solo está redirigiendo /myapp/y está aterrizando en la página de inicio predeterminada de nuestra aplicación https://ourapp.com/myapp/#/home.

He perdido casi un día para descubrir este comportamiento.

La solucion es:

Han cambiado la forma de la conexión de variables ocultas ( redirect) valor para sostener el fragmento de hash anexando window.location.hashjunto con el valor existente. Similar al siguiente código

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

Después de este cambio, la redirectvariable oculta almacena el valor de URL solicitado por el usuario /myapp/#/pending/requestsy SiteMinderlo redirige a /myapp/#/pending/requestsIE.

La solución anterior está funcionando bien en los tres navegadores Chrome, Firefox and IE.

Gracias a @AlexFord por la explicación detallada y la solución a este problema.

Prathap Reddy
fuente