Php ხელს უშლის ფორმის ხელახლა გაგზავნას. როგორ შემიძლია თავიდან ავიცილოთ ფორმა შეტყობინების ხელახლა გაგზავნისგან? ფორმის ხელახლა გაგზავნის პრევენცია კლიენტის მხრიდან გადამისამართების გამოყენებით

ერთ დროს გამაკვირვეს კითხვა, თუ როგორ დავიცვა საიტის გვერდები ფორმის მონაცემების განმეორებით წარდგენისგან გვერდის განახლების დროს (თუ მანამდე იყო წარდგენა, რა თქმა უნდა).
ყველა ვებმასტერმა და დეველოპერმა ალბათ იცის, რომ თუ თქვენ დააწკაპუნეთ ღილაკზე „გაგზავნა“ ვებსაიტზე რაიმე ფორმის შევსებით, შემდეგ გაგზავნის შემდეგ, თუ ცდილობთ გვერდის განახლებას, ბრაუზერი გამოაჩენს გაგზავნას ხელახლა გაგზავნის დამადასტურებელ შეტყობინებას.
ზოგიერთ შემთხვევაში ეს შეიძლება იყოს მიუღებელი. მაგალითად, ელემენტარული ფორმის შემთხვევაში უკუკავშირი. როდესაც მომხმარებელმა შეავსო ფორმა და გაგზავნა შეტყობინება, შემდეგ კი მხოლოდ მისთვის ცნობილი მიზეზების გამო განაახლეს გვერდი, წერილი კვლავ გაიგზავნა. ეს შეიძლება, რა თქმა უნდა, არ იყოს ისეთი ფატალური შემთხვევა, როგორც მაგალითი. ყველაფერი გაცილებით მტკივნეულია, მაგალითად, ონლაინ მაღაზიაში შეკვეთის გაგზავნისას.
ამიტომ დავინტერესდი ამ პრობლემის გადაჭრის შესახებ და მივხვდი, რომ მხოლოდ ერთი გამოსავალი იყო: გადამისამართების გამოყენება სათაურის ფორმის („ადგილმდებარეობა: მისამართი“) გაგზავნის შემდეგ. იმათ. ეს მარტივია - გაგზავნის შემდეგ ჩვენ ვუწოდებთ გადამისამართებას (შეგიძლიათ იმავე გვერდზეც კი გადახვიდეთ) და ეს არის! გვერდის განახლება იქნება სუფთა, ყოველგვარი დასრულებული POST-ების და GET-ების გარეშე.

ყველაფერი კარგად იქნება, მაგრამ პირადად მე განვიცადე გარკვეული პრობლემები ამ მხრივ. ისინი შემდეგია. ადრე, გადამისამართებების გამოყენების გარეშე, ჩემს საიტებზე მონაცემების გაგზავნის მექანიზმი მუშაობდა შემდეგნაირად:
მომხმარებელი ავსებს ფორმას, აწკაპუნებს "გაგზავნას", სკრიპტი იღებს გაგზავნილ მონაცემებს, ამოწმებს მათ სისწორეს (ვალიდობა, საჭირო მონაცემების შევსება და ა.შ.) და პასუხობს - ან ოპერაცია წარმატებული იყო, ან მოხდა შეცდომა და შეცდომების სია (მაგალითად: შეცდომა - ველი „სახელი“ არ არის შევსებული. გაგზავნის გვერდზე კი ნაჩვენებია შესაბამისი შეტყობინება: გაგზავნა წარმატებულია თუ წარუმატებელი.
თუ წარდგენა წარმატებული არ არის, ფორმა რჩება ეკრანზე და მისი ველები ივსება მომხმარებლის მიერ შეყვანილი მონაცემებით. იმათ. მონაცემები აღებულია $_POST ცვლადიდან (თუ მეთოდი არის POST) და მოთავსებულია შესაბამის ველებში (ანუ დაბრუნდება პოსტიდან მის ველებში, რათა აღარ შევიდეს). ბოლოს და ბოლოს ყველა ღიზიანდება როცა ავსებ ფორმას და ღმერთმა ქნას რამე არასწორად შეიყვანო და როცა ცდილობ გამოგიგზავნო მესიჯი რომ რაღაც არასწორად არის შევსებული და ფორმა განახლებულია და ცარიელია. ისევ. და ერთი არასწორად შევსებული ველის გამო ისევ უნდა შეავსოთ.
ასე რომ, როგორც უკვე ვთქვი, წარუმატებლად შევსების შემთხვევაში, ფორმა ივსება $_POST-დან აღებული მონაცემებით და მომხმარებელს შეუძლია შეასწოროს არასწორი მონაცემები და ხელახლა გაგზავნოს ფორმა.
ყველაფერი კარგად იყო და ყველაფერი მუშაობდა.
მაგრამ შემდეგ გავაგზავნე გადამისამართების გამოყენებით და აღმოჩნდა, რომ ღილაკზე „გაგზავნა“ დაჭერის შემდეგ, თუ შევსება წარუმატებელი იყო, ფორმა განახლდა და შევსებული ველები მასში ვეღარ დარჩებოდა, რადგან ადრე ისინი ავტომატურად ივსებოდა $_POST მასივიდან, მაგრამ ახლა, მას შემდეგ რაც მოხდა გადამისამართება, $_POST წაიშალა, თითქოს გაგზავნა არ იყო.
მაგრამ ამ შემთხვევისთვისაც იყო გამოსავალი. გამოიყენეთ სესიები. იმათ. სათაურის დარეკვამდე გადაიტანეთ მონაცემები POST-დან სესიის ცვლადებზე და მხოლოდ ამის შემდეგ იმოქმედეთ მასთან გადამისამართების შემდეგ.
შედეგად, კოდი მნიშვნელოვნად გართულდა. გამართვა უფრო გართულდა, რადგან ზოგადად, ძნელია იმის დადგენა, თუ რა ემართება ფუნქციებს იმ მომენტში, როდესაც ხდება გადამისამართება. თუ რაიმე სახის შეცდომა დაუშვით კოდებში (რომელიც ჩნდება ზუსტად გაგზავნის მომენტში), მაშინ ის არც კი გამოჩნდება, რადგან მოხდება გადამისამართება და თქვენ ვერც კი იხილავთ შეცდომის შეტყობინებას.
ზოგადად, ჩემს კოდებში სათაურის დანერგვის შემდეგ, უფრო გამიჭირდა აპლიკაციებთან მუშაობა. შემუშავება/დახვეწა/შეცდომების ძიება უფრო გართულდა. მაგრამ ამაზეც ვერ ვიტყვი უარს.
და მე ვაგრძელებ კითხვას: არის თუ არა სხვა, უფრო ელეგანტური გადაწყვეტილებები?

ხშირად მიჩნდება კითხვები ფორმის ხელახალი გაგზავნის გაუქმებასთან დაკავშირებით. მაგალითად, თქვენ შექმენით ფორმა კომენტარის დასამატებლად და დაამატეთ დამმუშავებელი იმავე გვერდზე. შემდეგ კომენტარის დამატებისას იგი წარმატებით ემატება, მაგრამ როგორც კი მომხმარებელი დააჭერს F5-ს, ფორმა ხელახლა გაიგზავნება. და მომხმარებელს შეუძლია მარტივად დააჭიროს F5, თუ გვერდის ჩატვირთვას დიდი დრო დასჭირდება. შედეგად, 1 კომენტარის ნაცვლად იქნება 2, ან მეტიც. ამ სტატიაში მე გაჩვენებთ, თუ როგორ შეიძლება ამის თავიდან აცილება.

პირველი, მოდით შევხედოთ პრობლემას უფრო დეტალურად ამ კოდის გამოყენებით, როგორც მაგალითი:









"კვადრატის" ღილაკზე დაჭერით ნახავთ სკრიპტის შედეგს. მაგრამ როგორც კი მომხმარებელი დააჭერს F5-ს ამის შემდეგ, სკრიპტი კვლავ შესრულდება. ამ შემთხვევაში, ეს არ არის ისეთი კრიტიკული, როგორც კომენტარის დამატება, თუმცა, რატომ გჭირდებათ დამატებითი დატვირთვა სერვერზე?

ახლა მოდით ვისაუბროთ ამ პრობლემის გადაჭრის გზებზე. პირველი გზა არის დამუშავების სკრიპტის ცალკე ფაილად გამოყოფა. შემდეგ ფორმის ტეგის მოქმედების ატრიბუტში თქვენ უნდა დაამატოთ ბილიკი ამ სკრიპტში. და თავად სკრიპტმა სადმე უნდა შეინახოს თავისი მოქმედებების შედეგი, ან ცვლადები, რომლებიც მოვიდა სკრიპტში, და შემდეგ გადამისამართდეს უკან. ზოგადად, შეხედეთ სკრიპტის კოდს:

და ფორმის მქონე გვერდის კოდი ახლა ასე გამოიყურება:









ამ მიდგომის მინუსი აშკარაა - თქვენ უნდა შექმნათ სხვა ფაილი ასეთი მარტივი სკრიპტისთვის. მაშასადამე, მე გეტყვით მეორე მეთოდის შესახებ, თუ როგორ შეგიძლიათ თავიდან აიცილოთ ფორმის ხელახალი გაგზავნა:









აქ დამუშავება კვლავ ხდება იმავე ფაილში, მაგრამ მთავარი განსხვავება არის იმავე გვერდზე გადამისამართების არსებობა ბოლოს. შედეგად, გვერდი გადაიტვირთება ფორმის გაგზავნის შემდეგ და ბრაუზერი არ მოუწოდებს მომხმარებელს ფორმის ხელახლა გაგზავნას F5-ზე დაჭერისას.

ნება მომეცით შევაჯამოთ, როგორ გავაუქმოთ ფორმის ხელახლა გაგზავნა:

  • ან ჩაატარეთ დამუშავება ცალკე ფაილი, და შემდეგ გადამისამართება იქიდან უკან.
  • ან გააკეთეთ დამუშავება იმავე ფაილში, როგორც ფორმაში, მაგრამ დამუშავების შემდეგ გააკეთეთ გადამისამართება იმავე გვერდზე.

ასე კეთდება მარტივი სკრიპტებით. და, კომპლექსურებში, იგივე კეთდება საბოლოოდ.

ვთქვათ, ჩვენ ვაკეთებთ სკრიპტს, რომელიც იღებს მონაცემებს POST მეთოდის გამოყენებით გაგზავნილი ფორმიდან. სკრიპტმა მიიღო მონაცემები, დაამუშავა და აჩვენა გვერდი შედეგით. მაგრამ თუ მომხმარებელი გადაწყვეტს ამ მომენტში გვერდის განახლებას, ის დაინახავს მსგავს შეტყობინებას:

ამ გვერდის საჩვენებლად Firefox-მა უნდა გამოაგზავნოს ინფორმაცია, რომელიც გაიმეორებს ნებისმიერ ადრე შესრულებულ მოქმედებას (მაგალითად, ძიების მოთხოვნა ან ონლაინ შესყიდვა).

და ორი ღილაკი. ერთ-ერთ მათგანზე დაწკაპუნებით მოხდება მონაცემების ხელახლა გაგზავნა, რაც ხშირად არასასურველია. მეორეზე დაჭერით გვერდი არ განახლდება. ნებისმიერ შემთხვევაში, მომხმარებელი თავს კარგად არ გრძნობს ასეთი შეტყობინების გამო. მომხმარებლებს საერთოდ არ მოსწონთ ყველა სახის ამომხტარი ფანჯარა.

დასაწყისისთვის, მე გაჩვენებთ სკრიპტს, რომელსაც დავასრულებთ.

შეგიძლიათ ფორმა გაგზავნოთ ერთხელ, შემდეგ დააჭირეთ Ctrl+R და ნახოთ უბედური ფანჯარა. მოდი თავი დავაღწიოთ.

ოღონდ ჯერ ერთი სიტყვა პოსტის სპონსორისგან - საიტისთვის სასარგებლო შინაარსით სამსუნგის ტელეფონები, რომელიც გთავაზობთ თემებს Samsung gt s5230-ისთვის, ფონებისთვის და სხვა ნივთებისთვის.

ფორმის ხელახლა გაგზავნის პრევენცია სერვერის გადამისამართების გამოყენებით

ფორმის მონაცემების ხელახლა გაგზავნის თავიდან ასაცილებლად, შეგიძლიათ გააკეთოთ სერვერის გადამისამართება. ეს კეთდება ბრაუზერისთვის მდებარეობის სათაურის გაგზავნით სასურველი URL-ით. მაგალითად, ეს უნდა იყოს მადლობის გვერდი ფორმის შევსებისთვის. შემდეგ ჩვენ დავწერთ მსგავსი რამ:

ამ შემთხვევაში სერვერი მიიღებს მონაცემებს, დაამუშავებს და შედეგის ჩვენების ნაცვლად კლიენტს გაუგზავნის გვერდზე, სადაც ეს შედეგი იქნება ნაჩვენები.

ამ მეთოდის მინუსი არის ის, რომ მომხმარებელს შეუძლია დააჭიროს უკანა ღილაკს და დაბრუნდეს გადამისამართებულ გვერდზე. ის კვლავ გადააგდებს მას წინ და ამიტომ მომხმარებელი ძნელად შეძლებს ორი გვერდის დაბრუნებას იმ ფორმაში, რომელიც მან თავდაპირველად შეავსო.

ფორმის ხელახლა გაგზავნის პრევენცია კლიენტის მხრიდან გადამისამართების გამოყენებით

კლიენტის გადამისამართებას ეწოდება კლიენტის გადამისამართება, რადგან ეს ხდება კლიენტის მხარეს. ანუ ბრაუზერში. კლიენტის გადამისამართება შეიძლება მოხდეს JavaScript-ისა და მეტა ტეგების გამოყენებით.

JavaScript-ს აქვს ბრაუზერის ისტორიის გადაწერის უპირატესობა ისე, რომ მაშინაც კი, თუ მომხმარებელი დააჭერს ბრაუზერის უკანა ღილაკს, ისინი არ დაბრუნდებიან იმ გვერდზე, რომელიც დააბრუნა ფორმის დამმუშავებელმა. ანუ ფანჯარა მთლიანად გაქრება. მაგრამ ზოგიერთ ადამიანს აქვს JS გამორთული.

მეორეს მხრივ, META ტეგებს აქვს მრავალმხრივი უპირატესობა. ისინი გადამისამართებენ ყველას, ყოველთვის.

ოპტიმალური იქნება ამ ორი მეთოდის გაერთიანება. როგორ - აღწერს ალექსანდრე შურკაევმა ჩანაწერში ოპტიმალური გადამისამართება.

ჩვენ ვიყენებთ მის მეთოდს შემდეგნაირად.

ვცადოთ! ახლა, როგორც ხედავთ, არცერთი ფანჯარა არ ჩანს. რა გავაკეთეთ? ჩვენ შევამოწმეთ. თუ მონაცემები მიღებულია, ჩვენ ვაჩვენებთ ყველაფერს, რაც საჭიროა გადამისამართებისთვის. პრინციპში, ამის შემდეგ შეგიძლიათ გასვლაც კი, რათა არ დატვირთოთ ბრაუზერი არასაჭირო მონაცემებით, რომლებსაც მაინც ვერავინ ნახავს.