ti-enxame.com

Por que o HTTP não tem POST redirecionado?

Os redirecionamentos HTTP são feitos pelos códigos HTTP 301 e 302 (talvez outros códigos também) e um campo de cabeçalho conhecido como "Local", que possui o endereço do novo local a ser percorrido. No entanto, os navegadores sempre enviam uma solicitação "GET" para esse URL.

No entanto, muitas vezes você precisa redirecionar seu usuário para outro domínio via POST (pagamentos bancários, por exemplo). Este é um cenário comum e realmente um requisito. Alguém sabe por que um requisito tão comum foi negligenciado na especificação HTTP? A solução alternativa é enviar um formulário (com parâmetros em campos ocultos) com ação definida para o local de destino (o valor do campo de cabeçalho Localização) e usar setTimeout para enviar o formulário para o local de destino.

181
Saeed Neamati

No HTTP 1.1, existe um código de status ( 7 ) que indica que a solicitação deve ser repetida usando o mesmo método e postar dados .

Como outros já disseram, existe um potencial de uso indevido aqui, que pode ser o motivo pelo qual muitas estruturas aderem a 301 e 302 em suas abstrações. No entanto, com entendimento adequado e uso responsável, , você poderá realizar o que está procurando.

Observe que, de acordo com especificação do W3.org , quando METHOD não for HEAD ou GET, os agentes do usuário devem solicitar ao usuário antes de executar novamente a solicitação no novo local. Você também deve fornecer uma nota e um mecanismo de fallback para o usuário, caso os agentes antigos não tenham certeza do que fazer com um 307.

Usando este formulário:

<form action="Test307.aspx" method="post">
    <input type="hidden" name="test" value="the test" />
    <input type="submit" value="test" />    
</form>

E o Test307.aspx simplesmente retorna 307 com o Local: http://google.com , Chrome 13 e o Fiddler confirmam que "test = the test" é realmente postado no Google. É claro que a resposta é 405, já que o Google não permite o POST, mas mostra a mecânica.

Para obter mais informações, consulte Lista de códigos de status HTTP e W3.org spec .

307 Redirecionamento temporário (desde HTTP/1.1) Nesta ocasião, a solicitação deve ser repetida com outro URI, mas solicitações futuras ainda podem usar o URI original . 2 Em contraste com 303, o método de solicitação não deve ser alterado ao reemitir a solicitação original. Por exemplo, uma solicitação POST deve ser repetida usando outra solicitação POST.

187
David Ruttka

Eu encontrei uma boa explicação sobre isso página aqui .

As situações mais simples da WWW são transações "idempotentes", ou seja, aquelas que podem ser repetidas sem causar nenhum dano. Normalmente, essas transações são "GET", porque são recuperadas referências de URL simples (por exemplo, href = ou src = atributos em HTML) ou porque são envios de formulários usando o método GET. O redirecionamento de uma transação desse tipo é direto e não há perguntas: o cliente recebe a resposta de redirecionamento, incluindo um cabeçalho Location: que especifica o novo URL, e o cliente reage a ele reemitindo a transação para o novo URL. Há uma diferença entre os diferentes códigos de status 30x associados a esses redirecionamentos em sua capacidade de cache implícita, mas, caso contrário, eles são basicamente semelhantes (301 e 302) em resposta às solicitações GET.

As transações POST são diferentes, pois são definidas como não-idempotentes (como pedir uma pizza, votar ou o que for) e não devem ser arbitrariamente repetidas.

As especificações do protocolo HTTP foram projetadas para levar em consideração essa distinção: o método GET é definido como inerentemente idempotente, enquanto o método POST é definido como sendo, pelo menos potencialmente, não idempotente; as especificações exigem uma série de precauções a serem tomadas pelos agentes clientes (como navegadores) para proteger os usuários contra (re) enviar inadvertidamente uma transação POST que eles não pretenderam ou submeteram um POST em um contexto que eles não desejariam.

Embora eu não seja fã de restringir os usuários tecnicamente para impedir que causem problemas indesejados ou causem danos indesejados aos seus aplicativos, posso entender o ponto e faz sentido.

49
Falcon

GET (e alguns outros métodos) são definidos como 'SEGURO' na especificação http ( RFC 2616 ):

9.1.1 Métodos seguros

Os implementadores devem estar cientes de que o software representa o usuário em suas interações pela Internet e devem ter cuidado para permitir que o usuário esteja ciente de quaisquer ações que possa executar que possam ter um significado inesperado para si ou para outros.

Em particular, foi estabelecida a convenção de que os métodos GET e HEAD NÃO DEVEM ter o significado de executar uma ação que não seja a recuperação. Esses métodos devem ser considerados "seguros". Isso permite que os agentes usuários representar outros métodos, como POST, PUT e DELETE, de uma maneira especial, para que o usuário fique ciente do fato de que uma ação possivelmente insegura está sendo solicitada.

Naturalmente, não é possível garantir que o servidor não gere efeitos colaterais como resultado da execução de uma solicitação GET; de fato, alguns recursos dinâmicos consideram isso um recurso. A distinção importante aqui é que o usuário não solicitou os efeitos colaterais, portanto, não pode ser responsabilizado por eles.

Isso significa que uma solicitação GET nunca deve ter conseqüências sérias para o usuário, além de ver algo que ele pode não querer ver, mas uma solicitação POST pode alterar um recurso importante para eles ou outras pessoas.

Embora isso tenha mudado com o JavaScript, tradicionalmente havia interfaces de usuário diferentes - os usuários podiam disparar solicitações GET clicando nos links, mas precisavam preencher um formulário para acionar uma solicitação POST. Acho que os designers do HTTP desejavam manter a distinção entre métodos seguros e não seguros.

Também não acho que seja necessário redirecionar para um POST. Presumivelmente, qualquer ação que precise ser executada chamando uma função no código do servidor ou, se for necessário, em um servidor diferente, em vez de enviar um redirecionamento contendo uma URL para o navegador POST para, o servidor pode fazer uma solicitação para esse servidor, agindo como um proxy para o usuário.

2
bdsl