Fragmento de URL e redirecionamentos 302

136

É sabido que o fragmento de URL (a parte após #) não é enviado ao servidor.

Eu me pergunto, no entanto, como os fragmentos funcionam quando um redirecionamento de servidor (via status HTTP 302 e Location:cabeçalho) está envolvido.

Minha pergunta é realmente dupla:

  1. Se a URL original tiver um fragmento ( /original.php#foo) e um redirecionamento for feito /new.php, a parte do fragmento da URL original simplesmente se perde? Ou às vezes é aplicado ao novo URL?
    O novo URL estará /new.php#fooneste caso?

  2. Independentemente da URL original, se o servidor redirecionar para uma nova URL com um fragmento ( /new.php#foo), o fragmento será "respeitado"? Ou o servidor realmente não tem nenhum problema em interferir com o fragmento - e o navegador, portanto, o ignorará simplesmente acessando /new.php??

levik
fonte
1
Aqui você pode encontrar especificações da W3C: w3.org/TR/cuap#uri, cláusula 4.1. o fragmento deve ser preservado no redirecionamento.
Marcin

Respostas:

135

Atualização 2014-jun-27 :

O RFC 7231, Protocolo de transferência de hipertexto (HTTP / 1.1): Semântica e conteúdo , foi publicado como um PADRÃO PROPOSTO. No Changelog :

A sintaxe do campo de cabeçalho Location foi alterada para permitir todas as referências de URI, incluindo referências e fragmentos relativos, além de alguns esclarecimentos sobre quando o uso de fragmentos não seria apropriado. (Seção 7.1.2)

Os pontos importantes da Seção 7.1.2. Localização :

Se o valor do local fornecido em uma resposta 3xx (Redirecionamento) não tiver um componente de fragmento, um agente do usuário DEVE processar o redirecionamento como se o valor herda o componente de fragmento da referência de URI usado para gerar o destino da solicitação (ou seja, o redirecionamento herda fragmento da referência original, se houver).

Por exemplo, uma solicitação GET gerada para a referência do URI " http://www.example.org/~tim " pode resultar em uma resposta 303 (Consulte Outro) contendo o campo do cabeçalho:

Location: /People.html#tim

o que sugere que o agente do usuário redirecione para " http://www.example.org/People.html#tim "

Da mesma forma, uma solicitação GET gerada para a referência de URI " http://www.example.org/index.html#larry " pode resultar em uma resposta 301 (Movida permanentemente) contendo o campo de cabeçalho:

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

o que sugere que o agente do usuário seja redirecionado para " http://www.example.net/index.html#larry ", preservando o identificador de fragmento original.

Isso deve responder claramente às suas perguntas.

Atualizar END

esse é um problema aberto (não especificado) com a especificação HTTP atual . Ele é abordado em duas questões do grupo de trabalho httpbis da IETF :

# 6 permite fragmentos no Locationcabeçalho. 43 diz o seguinte:

Acabei de testar isso com vários navegadores.

  • Firefox e Safari usam o fragmento no cabeçalho do local.
  • O Opera usa o fragmento do URI de origem, quando presente, caso contrário, o fragmento do local de redirecionamento
  • O IE (8) ignora o fragmento no local URI, portanto, usará o fragmento do URI de origem, quando presente

Proposta:

"Nota: o comportamento em que os identificadores de fragmentos do URI original e o redirecionamento precisam ser combinados é indefinido; os Agentes do Usuário atuais realmente diferem sobre qual fragmento tem precedência."

[...]

Parece que IE8 faz usar o idenfitier fragmento de Location(a vi comportamento pode ser limitada a localhost).

Portanto, parece que temos um comportamento consistente para o Safari / IE / Firefox / Chrome (apenas testado), na medida em que o fragmento do cabeçalho Location é usado, independentemente do URI original.

Portanto, mudo minha proposta para documentar isso como comportamento esperado.

isso leva à resposta mais compatível com o navegador e à prova do futuro (porque esse problema acabará sendo padronizado) para sua pergunta:

R: fragmentos de URLs originais são descartados.

B: fragmentos do Locationcabeçalho são respeitados.

machado.
fonte
1
Eu tinha esquecido algumas regras de "reescrita" que defini nos servidores HTTP, que provavelmente foram implementadas como redirecionamentos 301. Como conseqüência, o IE continuava perdendo o identificador de fragmento porque, quando você tem vários redirecionamentos, os fragmentos definidos pelo primeiro redirecionamento tornam-se parte do URI de origem no segundo.
Eugene Yokota
A ópera 12.12 honra o fragmento no cabeçalho do local, quando presente.
Cabra
4
Nas versões atuais do Chrome e Firefox: A não é verdade. Na versão atual do Firefox: B não é verdadeira. No momento, se você precisar usar hashes (por exemplo, usando o roteamento do Backbone), parece que o redirecionamento baseado em javascript é sua única opção real.
precisa saber é o seguinte
O bloco citado parece se contradizer. Primeiro, ele diz "IE (8) ignora o fragmento no URI da localização, portanto, usa o fragmento do URI de origem, quando presente", depois diz "Parece que o IE8 usa o identificador de fragmento da Localização". O primeiro se refere a algo diferente do segundo?
Davidtbernal
B não é verdadeiro para o Chome 45.0.2454.85. B é verdadeiro para o Firefox 40.0.3.
Jingguo Yao
44

O Safari 5 e o IE9 e abaixo eliminam o fragmento do URI original se ocorrer um redirecionamento HTTP / 3xx. Se o cabeçalho Location na resposta especificar um fragmento, ele será usado.

O IE10 +, o Chrome 11+, o Firefox 4+ e o Opera "reconectam" o fragmento do URI original depois de um redirecionamento 3xx.

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

Veja mais discussões sobre esse problema em http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx

EricLaw
fonte
2
Na verdade, o IE10 ainda se comporta de maneira diferente das versões mais recentes do Firefox e Chrome. Parece preservar o fragmento da URL de origem no caso de um redirecionamento simples. E se o redirecionamento Locationcontiver um fragmento, ele será mantido corretamente. Mas se um redirecionado Locationcom um fragmento passar por outro redirecionamento 3xx, ele inexplicavelmente ignorará o fragmento do primeiro redirecionamento, o que não é consistente com os dois comportamentos anteriores. Chrome e Firefox o preservam de forma consistente.
odony 19/11/2013
Confirmei que você está correto. Veja o link final do teste nesta página: webdbg.com/test/redir/fragment
EricLaw
11

Apenas para que você saiba, aqui você pode encontrar as especificações adequadas. definindo como todos devem se comportar: http://www.w3.org/TR/cuap#uri - cláusula 4.1 - veja abaixo:

Quando um recurso (URI1) é movido, um redirecionamento HTTP pode indicar seu novo local (URI2).

Se o URI1 tiver um identificador de fragmento #frag, o novo destino que o agente do usuário deve estar tentando alcançar seria URI2 # frag. Se o URI2 já tiver um identificador de fragmento, #frag não deve ser anexado e o novo destino é URI2.

Errado: a maioria dos agentes de usuário atuais implementa redirecionamentos HTTP, mas não anexa o identificador de fragmento ao novo URI, o que geralmente confunde o usuário porque ele acaba com o recurso errado.

Referências:

Os redirecionamentos HTTP são descritos na seção 10.3 da especificação HTTP / 1.1 [RFC2616]. O comportamento necessário é descrito em detalhes em "Manipulando identificadores de fragmentos em URLs redirecionados" [RURL]. O termo "PURL (Persistent Uniform Resource Locator)" designa uma URL (um caso especial de um URI) que aponta para outro através de um redirecionamento HTTP. Para obter mais informações, consulte "Localizadores uniformes persistentes de recursos" [PURL]. Exemplo:

Suponha que um usuário solicite o recurso em http://www.w3.org/TR/WD-ruby/#changes e o servidor redirecione o agente do usuário para http://www.w3.org/TR/ruby/ . Antes de buscar esse último URI, o navegador deve anexar o identificador de fragmento #changes a ele: http://www.w3.org/TR/ruby/#changes .

Marcin
fonte
0

Publicando um problema semelhante com a solução enfrentada por mim.

Espero que ajude alguém com o mesmo requisito de preserving hash in IEredirecionamentos 302.

Adicionando partes essenciais da resposta em vez de links apenas

Usamos SiteMinderautenticação em nosso aplicativo.

Eu descobri que, após uma autenticação bem-sucedida, SiteMinderestá fazendo 302 redirectiona página de aplicativo solicitada pelo usuáriovalue usando a variável oculta do formulário de login (onde armazena a URL solicitada pelo usuário /myapp/- without hash fragmentjá que não será enviada ao servidor) com um nome semelhante redirect. Exemplo de formulário abaixo

Exemplo de formulário de login

Como o valor daredirect variável oculta contém apenas sem fragmento de hash e é um redirecionamento 302, o fragmento de hash é removido automaticamente pelo IE mesmo antes de chegar ao nosso aplicativo e quaisquer que sejam as soluções que estamos tentando no código do aplicativo não estão funcionando./myapp/

O IE está redirecionando /myapp/apenas para e está chegando na página inicial padrão do nosso aplicativo https://ourapp.com/myapp/#/home.

Já perdi quase um dia para descobrir esse comportamento.

A solução é:

Alterou o valor da variável oculta ( ) do formulário de logon para manter o fragmento de hash anexando junto com o valor existente. Semelhante ao código abaixoredirectwindow.location.hash

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

Após essa alteração, a redirectvariável oculta está armazenando o valor da URL solicitada pelo usuário /myapp/#/pending/requestse a SiteMinderestá redirecionando para o /myapp/#/pending/requestsIE.

A solução acima está funcionando bem nos três navegadores Chrome, Firefox and IE.

Agradecemos a @AlexFord pela explicação detalhada e por fornecer a solução para esse problema.

Prathap Reddy
fonte