2013-07-25 12 views
20

Esiste un codice di stato HTTP per richiedere a un client di eseguire nuovamente la stessa richiesta?Statuscode HTTP per riprovare la stessa richiesta

Sono di fronte a una situazione in cui il server deve "attendere" che un blocco scompaia durante l'elaborazione di una richiesta. Ma quando il blocco scompare, le richieste potrebbero essere vicine al limite di timeout. Quindi, invece, una volta sbloccato il blocco, vorrei chiedere al cliente di eseguire nuovamente la stessa richiesta.

Il meglio che mi viene in mente è un 307 HTTP nella stessa posizione, ma sono preoccupato che alcuni browser non possano acquistare in questo (reindirizzamento del ciclo di reindirizzamento).

+1

Aggiungere un parametro di modifica dell'URL, quindi non sembrerà un loop. – Barmar

+0

Buone risposte a http://stackoverflow.com/q/9794696/520567 (202 e 423) – akostadinov

risposta

24

La risposta corretta, quando un server non è in grado di gestire una richiesta, è 503 Service Unavailable. Quando la condizione è temporanea, come nel tuo caso, puoi impostare l'intestazione Retry-After in modo che il client sappia per quanto tempo deve attendere prima di riprovare.

Tuttavia, questo non costringerà il browser a eseguire nuovamente la richiesta: è qualcosa che dovresti gestire in javascript. Ad esempio, ecco come si potrebbe eseguire una richiesta POST riprovare Ajax in jQuery:

function postData() { 
    $.ajax({ 
    type: 'POST', 
    url: '503.php', 
    success: function() { 
     /* 
     Do whatever you need to do here when successful. 
     */ 
    }, 
    statusCode: { 
     503: function(jqXHR) { 
     var retryAfter = jqXHR.getResponseHeader('Retry-After'); 
     retryAfter = parseInt(retryAfter, 10); 
     if (!retryAfter) retryAfter = 5; 
     setTimeout(postData, retryAfter * 1000); 
     } 
    } 
    }); 
} 

Si noti che il codice di cui sopra supporta solo un colpo di testa Retry-After in cui il ritardo di tentativo è specificato in secondi. Se vuoi supportare le date che richiedono un po 'più di lavoro. Nel codice di produzione consiglio anche un contatore di qualche tipo per assicurarmi di non continuare a riprovare per sempre.

Per quanto riguarda l'utilizzo di un codice di stato 307 per ripetere automaticamente la richiesta, non penso che sia una buona idea. Anche se si aggiunge un parametro retry per aggirare il rilevamento del loop del browser (che sembra un orribile hack), non funzionerà ancora su una richiesta POST. Da RFC2616:

Se il codice 307 di stato ricevuto in risposta ad una richiesta diversa da GET o HEAD, l'agente utente NON DEVE reindirizzare automaticamente la richiesta a meno che non può essere confermata dall'utente.

Mentre alcuni browser sono noti per ignorare questo requisito, non è sicuramente corretto, e non è qualcosa su cui si vorrebbe fare affidamento.

E se non si sta usando una richiesta POST, quasi certamente dovrebbe esserlo. Ricordare che una richiesta GET should not have any side effects e per impostazione predefinita la risposta verrà memorizzata nella cache. Dalla descrizione del tuo problema, sembra molto probabile che la tua richiesta stia facendo qualcosa che ha effetti collaterali.

+0

Non penso che l'errore del server sia una risposta corretta qui. Per me qualcosa nella gamma 4xx avrebbe più senso. Ho letto http://stackoverflow.com/q/9794696/520567 - lì 423 è utile per il caso d'uso dell'ops. Anche 202 è buono per altri casi d'uso. – akostadinov

3

Utilizzare il 307 reindirizzamento, ma aggiungere un contatore di tentativi:

http://path/to/server?retry=3 

Questo renderà l'URL diverso su ogni riprovare, impedendo il rilevamento loop. E il server potrebbe controllare per riprovare a raggiungere un limite e interrompere con un errore quando ciò accade, quindi l'utente non aspetta per sempre.

+0

Non penso che un reindirizzamento HTTP permetta di modificare i parametri? Nota che 307 deve funzionare per qualsiasi metodo. Quindi se la richiesta originale era un POST con 'form-data/multipart', non penso di poter aggiungere un parametro' retry'? – Jeroen

+0

È possibile reindirizzare a qualsiasi URL e può contenere parametri, quindi perché non potrebbero essere diversi dai parametri originali?Ma hai ragione che questo non funzionerà con un POST - non invierà di nuovo il modulo al nuovo URL. – Barmar

Problemi correlati