Ketika membuat aplikasi berbasis Web, pasti pernah (jika bukan sering) berurusan dengan form html. Dimana form merupakan sarana interaksi user dengan aplikasi atau halaman Web yang dikunjunginya tersebut. Form yang memuat data penting dan sensitif biasanya akan menggunakan metode POST dalam pengiriman datanya. Cara kerjanya sederhana, user mengisi data di form yang ada kemudian submit form tersebut, halaman web yang menerima form tersebut kemudian memproses data yang dikirimkan, kemudian tampilkan pesan atau hasil dari pemrosesan data tersebut, selesai.
Masalah yang muncul adalah ketika user melakukan refresh atau reload, misalnya dengan menekan tombol F5 di browser, maka form yang tadinya disubmit akan disubmit ulang, meskipun memang biasanya browser akan meminta konfirmasi terlebih dahulu. Seperti yang ditampilkan pada gambar di bawah ini.
Apakah ada masalah dengan hal tersebut ? Mari kita bahas. Misalkan kita membuat website e-commerce, atau toko online, user mengisi form order barang, kemudian disubmit, dan kemudian disubmit lagi. Tentunya di aplikasi kita akan mencatat ada 2 buah transaksi yang sama persis, yang belum tentu si user memang benar ingin melakukan 2 buah order tersebut. Apakah ini fatal? Bisa iya bisa tidak. Bukan masalah, jika emang kita melakukan konfirmasi ke pembeli, namun bisa fatal jika website kita adalah website yang menganggap bahwa transaksi online adalah hal yang valid dan absolut. Dengan demikian website kita akan mencatat ada 2 order, padahal user hanya bermaksud order 1 kali.
Bagaimana mengatasi hal ini ? Sebelumnya, perlu diingat bahwa form HTML dikirimkan menggunakan protokol HTTP, dengan demikian tentunya, response yang diharapkan oleh browser adalah dalam format protokol HTTP pula.
Kunci dari penanganan masalah double POST submit ini adalah meminta browser menuju ke halaman lain setelah form selesai diproses.
Mari kita lihat contoh kasusnya.
File php yang menampilkan pesan atau hasil setelah form diproses. Katakanlah namanya prg-hasil.php
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <html> <head> <title>Http Post Redirect Get</title> <style type='text/css'> body { margin: 20px; } body, body * { font-family: sans-serif; font-size: 14pt; } </style> </head> <body> <h3>Form sudah disubmit</h3> <?php if(isset($_POST['submit'])) { // proses form kiriman // misalnya, simpan ke database atau yang lain // ..... echo "<h4>Form disubmit kesini menggunakan POST, apabila di refresh, maka form akan dikirim ulang</h4>"; } ?> </body> </html> |
Berikut adalah file berisi formulir html.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <html> <head> <title>Http Post Redirect Get</title> <style type='text/css'> body { margin: 20px; } body, body * { font-family: sans-serif; font-size: 14pt; } </style> </head> <body> <h3>Form Testing Post Redirect Get</h3> <form method='post' action='prg-hasil.php'> Input 1 <input type='text' name='input1' value=''/><br> Input 2 <input type='text' name='input2' value=''/><br> <br/> <input type='submit' value='Submit' name='submit'> </form> </body> </html> |
Perhatikan baris <form method='post' action='prg-hasil.php'>
, yang menandakan bahwa form ini akan dikirimkan ke file prg-hasil.php
. Tidak ada yang salah dengan ini, namun coba jalankan dan kemudian setelah muncul pesan submit, maka form akan disubmit ulang, setelah browser melakukan konfirmasi tentunya.
Solusinya adalah, kita akan melakukan submit form ke file yang berbeda dengan file yang akan menampilkan hasilnya. Contoh dibawah ini, kita akan mengirimkan form ke dirinya sendiri, kemudian setelah form diproses, baru akan menuju ke file prg-hasil.php
untuk menampilkan pesan/hasil pemrosesan form.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <html> <head> <title>Http Post Redirect Get</title> <style type='text/css'> body { margin: 20px; } body, body * { font-family: sans-serif; font-size: 14pt; } </style> </head> <body> <?php if(!isset($_POST['submit'])){ ?> <h3>Form Testing Post Redirect Get</h3> <form method='post'> Input 1 <input type='text' name='input1' value=''/><br> Input 2 <input type='text' name='input2' value=''/><br> <br/> <input type='submit' value='Submit' name='submit'> </form> <?php } else { // proses form kiriman // misalnya, simpan ke database atau yang lain // ..... // setelah selesai tampilkan pesan // disinilah kunci dari tutorial ini, // menggunakan header 302 Found, // dilanjutkan dengan header Location // hal ini berarti meminta browser untuk menuju ke halaman yang dituju // namun, request ini akan dilakukan dengan menggunakan HTTP GET // hal ini bertujuan untuk mencegah POST berulang ulang, apabila // user melakukan refresh atau reload pada browser nya header('HTTP/1.1 302 Found'); header('Location: prg-hasil.php'); } ?> </body> </html> |
Silakan jalankan dan setelah menampilkan pesan hasil form, lakukan refresh. Form tidak akan dikirim ulang. Hal ini dikarenakan terutama pada 2 baris
1 2 | header('HTTP/1.1 302 Found'); header('Location: prg-hasil.php'); |
yang mana mengirimkan Header HTTP dengan response code 302, yang berarti bahwa halaman ini ada namun bukan disini, namun ada di file prg-hasil.php
. Dengan demikian, browser akan menuju halaman yang diberikan disini, namun tanpa membawa form yang tadi disubmit. Teknik ini dikenal dengan nama Post/Redirect/Get.
Dengan demikian, bisa mengatasi masalah double submit POST. Sekedar tambahan, komunikasi antara file yang satu dan lainnya bisa menggunakan session, cookie, atau media lainnya, termasuk database.
Berikut adalah ilustrasi yang melukiskan masalah dan solusi dari double POST ini. Gambar diambil dari Wikipedia.
Demikian, semoga tulisan ini berguna untuk kita semua.