Anulați retrimiterea formularului. PHP: Cum să împiedici trimiterea din nou a unui formular

01.07.2020 Efecte de text

La un moment dat am fost nedumerit de întrebarea cum să protejez paginile site-ului de trimiterea repetată a datelor de formular în timpul unei actualizări a paginii (dacă a existat o trimitere înainte de aceasta, desigur).
Fiecare webmaster și dezvoltator știe probabil că dacă ați făcut clic pe butonul „trimite” de pe un site web completând un formular, apoi după trimitere, dacă încercați să reîmprospătați pagina, browserul va afișa un mesaj de confirmare a retrimiterii.
În unele cazuri, acest lucru poate fi inacceptabil. De exemplu, în cazul unui formular de feedback de bază. Când utilizatorul a completat formularul și a trimis un mesaj și apoi, dintr-un motiv cunoscut doar de el, a reîmprospătat pagina, scrisoarea a fost trimisă din nou. Acesta poate, desigur, să nu fie un caz atât de fatal, doar ca exemplu. Totul este mult mai dureros, de exemplu, atunci când trimiteți o comandă într-un magazin online.
Așa că m-am întrebat despre găsirea unei soluții la această problemă și mi-am dat seama că există o singură soluție: utilizarea unei redirecționări după trimiterea formularului de antet ('locație: adresă'). Aceste. Este simplu – după trimitere, apelăm la o redirecționare (poți chiar să mergi pe aceeași pagină) și gata! Actualizarea paginii va fi curată, fără POST-uri și GET-uri finalizate.

Totul ar fi bine, dar personal am întâmpinat câteva probleme cu asta. Ele sunt după cum urmează. Anterior, fără a utiliza redirecționări, mecanismul de trimitere a datelor pe site-urile mele funcționa după cum urmează:
Utilizatorul completează formularul, dă clic pe „trimite”, scriptul acceptă datele trimise, le verifică corectitudine (validitatea, completarea datelor solicitate etc.) și dă un răspuns - fie operația a avut succes, fie a apărut o eroare și o listă de erori (de exemplu: eroare - câmpul „nume” nu este completat. Și pe pagina de trimitere este afișat mesajul corespunzător: trimiterea a reușit sau nu.
Dacă trimiterea nu are succes, formularul rămâne pe ecran și câmpurile sale sunt completate cu datele introduse de utilizator. Aceste. datele sunt preluate din variabila $_POST (dacă metoda este POST) și plasate în câmpurile corespunzătoare (adică, returnate din post în câmpurile sale pentru a nu le mai introduce). La urma urmei, toată lumea se enervează când ai completat un formular și Doamne ferește că ai introdus ceva incorect, iar când încerci să ți-l trimiți, se dă un mesaj că ceva a fost completat incorect, iar formularul este actualizat și este gol din nou. Și din cauza unui câmp completat incorect, trebuie să îl completați din nou.
Așadar, așa cum am spus deja, în caz de completare nereușită, formularul rămâne completat cu date preluate din $_POST, iar utilizatorul poate corecta datele incorecte și poate trimite din nou formularul.
Totul a fost bine și totul a funcționat.
Dar apoi l-am trimis folosind redirecționare și s-a dovedit că după apăsarea butonului „trimite”, dacă completarea nu a reușit, formularul era actualizat și câmpurile completate nu mai puteau rămâne în el, deoarece Anterior, acestea erau completate automat din matricea $_POST, dar acum, după ce a avut loc redirecționarea, $_POST a fost șters ca și cum nu ar fi fost nicio trimitere.
Dar a existat o cale de ieșire și pentru acest caz. Folosiți sesiuni. Aceste. Înainte de a apela antetul, transferați datele de la POST la variabilele de sesiune și abia apoi operați cu el după redirecționare.
Drept urmare, codul a devenit semnificativ mai complicat. Depanarea a devenit mai complicată deoarece În general, este dificil de determinat ce se întâmplă cu funcțiile în momentul în care are loc redirecționarea. Daca ai facut vreo greseala in coduri (care apare exact in momentul trimiterii), atunci nici nu va fi afisata, deoarece va avea loc o redirecționare și nici măcar nu veți vedea mesajul de eroare.
În general, după implementarea antetului în codurile mele, mi-a devenit mai dificil să lucrez cu aplicațiile mele. Dezvoltarea/rafinarea/căutarea erorilor a devenit mai complicată. Dar nici asta nu pot refuza.
Și continui să mă întreb: există alte soluții, mai elegante?

Să presupunem că realizăm un script care acceptă date dintr-un formular trimis folosind metoda POST. Scriptul a primit datele, le-a procesat și a afișat o pagină cu rezultatul. Dar dacă utilizatorul decide să reîmprospăteze pagina în acest moment, va vedea un mesaj ca acesta:

Pentru a afișa această pagină, Firefox trebuie să trimită informații care vor repeta orice acțiune efectuată anterior (de exemplu, o cerere de căutare sau o achiziție online).

Și doi nasturi. Făcând clic pe unul dintre ele, datele vor fi retrimise, ceea ce este adesea nedorit. Făcând clic pe al doilea nu va reîmprospăta pagina. În orice caz, utilizatorul nu se simte bine în legătură cu un astfel de mesaj. În general, utilizatorilor nu prea le plac toate tipurile de ferestre pop-up.

Pentru început, vă voi arăta scenariul pe care îl vom finaliza.

Puteți trimite formularul o dată, apoi apăsați Ctrl+R și vedeți fereastra nefastă. Să scăpăm de el.

Dar mai întâi, un cuvânt de la sponsorul postării - un site cu conținut util pentru telefoanele Samsung, care oferă teme pentru Samsung gt s5230, imagini de fundal și alte chestii.

Prevenirea retrimiterii formularelor folosind redirecționarea serverului

Pentru a preveni trimiterea din nou a datelor din formular, puteți face o redirecționare a serverului. Acest lucru se face trimițând browserului un antet Locație cu adresa URL dorită. De exemplu, aceasta ar trebui să fie o pagină de mulțumire pentru completarea formularului. Apoi vom scrie ceva de genul:

În acest caz, serverul va primi datele, le va procesa și, în loc să arate rezultatul, va trimite clientul la o pagină unde va fi afișat acest rezultat.

Dezavantajul acestei metode este că utilizatorul poate face clic pe butonul Înapoi și poate reveni la pagina redirecționată. Ea îl va arunca din nou înainte și astfel utilizatorul cu greu va putea întoarce două pagini înapoi la formularul pe care l-a completat inițial.

Prevenirea retrimiterii formularelor folosind o redirecționare la nivelul clientului

O redirecționare client se numește redirecționare client deoarece are loc pe partea clientului. Adică în browser. Redirecționarea clientului poate avea loc utilizând JavaScript și metaetichete.

JavaScript are avantajul de a suprascrie Istoricul browserului, astfel încât, chiar dacă utilizatorul apasă butonul înapoi al browserului, acesta nu va reveni la pagina pe care a returnat-o handlerul de formulare. Adică fereastra va dispărea complet. Dar unii oameni au JS dezactivat.

Etichetele META, pe de altă parte, au avantajul de a fi versatile. Îi redirecționează pe toată lumea, întotdeauna.

Ar fi optim să combinați aceste două metode. Cum - Alexander Shurkayev a descris redirecționarea optimă în nota sa.

Folosim metoda lui după cum urmează.

Să încercăm! Acum, după cum puteți vedea, nu apare nicio fereastră. Ce am făcut? Am verificat. Dacă datele au fost primite, afișăm tot ce este necesar pentru redirecționare. În principiu, după aceasta poți chiar să ieși, pentru a nu încărca browserul cu date inutile pe care oricum nimeni nu le va vedea.

Procesul de trimitere a formularului HTML poate dura câteva secunde înainte ca formularul să fie trimis cu succes și să fie afișată pagina de răspuns. Utilizatorii care nu au suficientă răbdare pot face clic pe butonul Trimite de mai multe ori, determinând retrimiterea formularului. De obicei, aceasta nu este o problemă, dar în unele cazuri puteți face ceva pentru a preveni să se întâmple.
Mai jos veți găsi două trucuri simple pentru a preveni mesajele duble, puteți folosi oricare dintre acestea sau o combinație a acestora.

Prevenirea trimiterilor multiple cu Javascript

Probabil că folosirea Javascript pentru a preveni retrimiterea formularului este cea mai ușoară cale. Când utilizatorul trimite formularul, puteți dezactiva butonul „Trimite” și îi puteți schimba numele cu ceva mai clar: „Se trimite, vă rugăm să așteptați...”

Primul pas este să setați un id unic, de exemplu id="myButton":

Al doilea (și ultimul) pas este să specificați două comenzi Javascript în fișierul . Prima comandă va dezactiva butonul Trimitere după ce formularul este trimis, iar a doua va schimba textul butonului pentru a oferi utilizatorului o idee despre ceea ce se întâmplă. Următorul cod trebuie adăugat la etichetă:

Eticheta de formular va arăta astfel: