Perché HTTP non ha il reindirizzamento POST?

144

I reindirizzamenti HTTP vengono fatti tramite i codici HTTP 301 e 302 (forse anche altri codici) e un campo di intestazione noto come "Posizione" che ha l'indirizzo del nuovo posto dove andare. Tuttavia, i browser inviano sempre una richiesta "GET" a quell'URL.

Tuttavia, molte volte è necessario reindirizzare il tuo utente a un altro dominio tramite POST (pagamenti bancari, ad esempio). Questo è uno scenario comune e davvero un requisito. Qualcuno sa perché un tale requisito comune è stato trascurato nelle specifiche HTTP? La soluzione alternativa è inviare un modulo (con parametri nei campi nascosti) con l'azione impostata sulla posizione di destinazione (il valore del campo Posizione ) e utilizzare setTimeout per inviare il modulo alla posizione di destinazione .

    
posta Saeed Neamati 10.08.2011 - 10:49
fonte

3 risposte

162

In HTTP 1.1, in realtà è un codice di stato ( 307 ) che indica che la richiesta deve essere ripetuta utilizzando lo stesso metodo e postare i dati .

Come altri hanno già detto, c'è un potenziale di abuso qui che potrebbe essere il motivo per cui molti framework si attaccano a 301 e 302 nelle loro astrazioni. Tuttavia, con comprensione adeguata e utilizzo responsabile dovresti essere in grado di realizzare ciò che stai cercando.

Da notare che secondo la specifica W3.org , quando METHOD non è HEAD o GET , i programmi utente dovrebbero richiedere all'utente prima di rieseguire la richiesta nella nuova posizione. Dovresti anche fornire una nota e un meccanismo di fallback per l'utente nel caso in cui i vecchi interpreti non siano sicuri su cosa fare con un 307.

Utilizza questo modulo:

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

E avendo Test307.aspx restituisci semplicemente 307 con il percorso: link , Chrome 13 e Fiddler confermano che "test = il test" è effettivamente pubblicato a Google. Ovviamente l'ulteriore risposta è un 405 poiché Google non consente il POST, ma mostra i meccanismi.

Per ulteriori informazioni, consulta Elenco dei codici di stato HTTP e Specifiche 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.

    
risposta data 10.08.2011 - 15:49
fonte
45

Ho trovato una buona spiegazione su questa pagina qui .

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.

Anche se non sono un fan di limitare tecnicamente gli utenti a impedire che causino un caos indesiderato o che facciano danni indesiderati alle loro applicazioni, posso capire il punto e ha senso.

    
risposta data 10.08.2011 - 11:08
fonte
2

GET (e alcuni altri metodi) sono definiti come "SICURO" nelle specifiche 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.

Ciò significa che una richiesta GET non dovrebbe mai avere conseguenze gravi per l'utente, oltre a vedere qualcosa che potrebbe non voler vedere, ma una richiesta POST potrebbe cambiare una risorsa che è importante per loro o per altre persone.

Sebbene ciò sia cambiato con JavaScript, tradizionalmente c'erano diverse interfacce utente: gli utenti potevano attivare le richieste GET facendo clic sui collegamenti, ma dovevano compilare un modulo per attivare una richiesta POST. Penso che i progettisti di HTTP volessero mantenere la distinzione tra metodi sicuri e non sicuri.

Inoltre, non penso che dovrebbe mai essere necessario reindirizzare a un POST. Ogni azione che deve essere eseguita può presumibilmente essere eseguita chiamando una funzione all'interno del codice lato server, o se deve avvenire su un server diverso, invece di inviare un reindirizzamento contenente un URL per il POST al server, il server potrebbe fare una richiesta a quel server stesso, comportandosi come un proxy per l'utente.

    
risposta data 11.03.2018 - 11:27
fonte

Leggi altre domande sui tag