Por que o HTTP não tem redirecionamento POST?

144

Os redirecionamentos HTTP são feitos através dos códigos HTTP 301 e 302 (talvez outros códigos também) e um campo de cabeçalho conhecido como "Local", que tem o endereço do novo local a ser utilizado. No entanto, os navegadores sempre enviam uma solicitação "GET" para essa 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 Local ) e usar setTimeout para enviar o formulário para o local de destino .

    
por Saeed Neamati 10.08.2011 / 10:49
fonte

3 respostas

162

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

Como outros já disseram, existe um potencial para uso indevido aqui, o que pode ser o motivo pelo qual muitos frameworks aderem a 301 e 302 em suas abstrações. No entanto, com uma compreensão adequada e uso responsável, você deve ser capaz de realizar o que está procurando.

Observe que, de acordo com a especificação do W3.org , quando o METHOD não é HEAD ou GET , agentes do usuário devem avisar o usuário antes de reexecutar 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 de usuários 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 com o Test307.aspx, basta retornar 307 com o local: link , o Chrome 13 e o Fiddler confirmam que "teste = teste" é realmente publicado para o Google. É claro que a resposta adicional é um 405, já que o Google não permite o POST, mas mostra a mecânica.

Para mais informações, consulte Lista de códigos de status HTTP e o Especificação do W3.org .

307 Temporary Redirect (since HTTP/1.1) In this occasion, the request should be repeated with another URI, but future requests can still use the original URI.2 In contrast to 303, the request method should not be changed when reissuing the original request. For instance, a POST request must be repeated using another POST request.

    
por 10.08.2011 / 15:49
fonte
45

Encontrei uma boa explicação sobre esta página aqui .

The simplest situations on the WWW are "idempotent" transactions, i.e those which can be repeated without causing any harm. These are typically "GET" transactions, either because they are retrieval of straightforward URL references (e.g href= or src= attributes in HTML), or because they are form submissions using the GET method. Redirecting a transaction of that kind is straightforward, and no questions asked: the client receives the redirection response, including a Location: header that specifies the new URL, and the client reacts to it by re-issuing the transaction to the new URL. There's a difference between the different 30x status codes associated with these redirections in their implied cacheability, but otherwise they are basically similar (301 and 302) in response to GET requests.

POST transactions are different, since they are defined to be, in principle, non-idempotent (such as ordering a pizza, casting a vote or whatever) and mustn't be arbitrarily repeated.

The HTTP protocol specifications are designed to take this distinction into account: the GET method is defined to be inherently idempotent, whereas the POST method is defined to be, at least potentially, non-idempotent; the specifications call for a number of precautions to be taken by client agents (such as browsers) for protecting users against inadvertently (re)submitting a POST transaction which they had not intended, or submitting a POST into a context which they would not have wanted.

Embora eu não seja um fã de restringir tecnicamente os usuários para evitar que eles causem caos indesejados ou causem danos indesejados em seus aplicativos, posso entender o ponto e isso faz sentido.

    
por 10.08.2011 / 11:08
fonte
2

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

9.1.1 Safe Methods

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

Isso significa que uma solicitação GET nunca deve ter nenhuma conseqüência séria para o usuário, além de ver algo que talvez não queira ver, mas uma solicitação POST pode alterar um recurso importante para ela ou para outras pessoas.

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

Eu também não acho que seja necessário redirecionar para um POST. Qualquer ação que precise ser executada pode presumivelmente ser feita chamando uma função dentro do código do lado do servidor, ou se precisar acontecer em um servidor diferente, em vez de enviar um redirecionamento contendo uma URL para o navegador para POST, o servidor poderia fazer um pedido para o próprio servidor, agindo como um proxy para o usuário.

    
por 11.03.2018 / 11:27
fonte