An action within a controller generates the next id from the database and displays it on screen as reference. How can I prevent the action being called again if the user clicks refresh.
The post-redirect-get pattern with Zend Framework would generally involve leaving the action of the form empty (so it posts to itself) and then redirecting when you don't want to display the form again (so upon success).
public function newAction() {
$form = new Form_Foo();
if($this->_request->isPost()) {
if($form->isValid($this->_request->getPost()) {
//save or whatever
return $this->_redirect('path/to/success');
}
// else fall through
}
$this->view->form = $form;
}
if ($this->isPost()) {
// Check validation
if ($error) {
$dataToMove = array();
// $dataToMove is array that you want to pass with redirect
// It can be an array of errors or form data that user has entered
// Use FlashMessenger helper to pass data to redirection via Zend_Session
$this->_helper->getHelper('FlashMessenger')->addMessage($dataToMove);
// And redirect page to form url
$this->_helper->getHelper('Redirector')->goToUrl('/form/url/');
}
// If not posted, get data from FlashMessenger
$data = $this->_helper->getHelper('FlashMessenger')->getMessages();
// And assign to view or make that you want
$this->view->formData = $data;
Although this is older post people still come here for answers, so let me help a bit more.
Redirecting form is great and useful but we are still not preventing peple from clicking back button and resubmitting that way.
The solution is to either show the form as popup and make it disapear when done (easily done with jquery) or generate unique id for each transaction and checking if id was previously used.
See article: http://www.boutell.com/newfaq/creating/stoprefresh.html
Hope it helps.
You can do this by implementing a 302 redirect
header('HTTP/1.1 302 Found');
header('Location: displayId.php?id=5');
die();
Assuming you have these pages
form.php
processForm.php
displayId.php
Form.php only displays form and sends data via POST to processForm.php.
Within processForm.php you can parse data and issue the redirect to displayId.php with id you want to display in GET parameter.
This way when user refreshes the page (displayId.php) the form data is not processed again.
I know you're trying to do this in Zend Framework but I'm just saying I'm after the same functionality. Just moved everything to ZF and I'm quite disappointed to see that this functionality isn't built in.
I used to have every form submit to process.php which processed all GET, POST requests and then saved the results (like error and success messages) and redirected you to the new place.
If $_SESSION['post_data'] was set, I would $_POST = $_SESSION['post_data']; and then remove it from the session.
This worked great but now I'm gonna need the same in ZF :D As I say... a little disappointed as I don't believe ANYONE wants a dialog to appear asking about resubmitting data.. what the hell does that mean to your enduser? nothing!
Related
Page one contains an HTML form. Page two - the code that handles the submitted data.
The form in page one gets submitted. The browser gets redirected to page two. Page two handles the submitted data.
At this point, if page two gets refreshed, a "Confirm Form Resubmission" alert pops up.
Can this be prevented?
There are 2 approaches people used to take here:
Method 1: Use AJAX + Redirect
This way you post your form in the background using JQuery or something similar to Page2, while the user still sees page1 displayed. Upon successful posting, you redirect the browser to Page2.
Method 2: Post + Redirect to self
This is a common technique on forums. Form on Page1 posts the data to Page2, Page2 processes the data and does what needs to be done, and then it does a HTTP redirect on itself. This way the last "action" the browser remembers is a simple GET on page2, so the form is not being resubmitted upon F5.
You need to use PRG - Post/Redirect/Get pattern and you have just implemented the P of PRG. You need to Redirect. (Now days you do not need redirection at all. See this)
PRG is a web development design pattern that prevents some duplicate form submissions which means, Submit form (Post Request 1) -> Redirect -> Get (Request 2)
Under the hood
Redirect status code - HTTP 1.0 with HTTP 302 or HTTP 1.1 with HTTP 303
An HTTP response with redirect status code will additionally provide a URL in the location header field. The user agent (e.g. a web browser) is invited by a response with this code to make a second, otherwise identical, request to the new URL specified in the location field.
The redirect status code is to ensure that in this situation, the web user's browser can safely refresh the server response without causing the initial HTTP POST request to be resubmitted.
Double Submit Problem
Post/Redirect/Get Solution
Source
Directly, you can't, and that's a good thing. The browser's alert is there for a reason. This thread should answer your question:
Prevent Back button from showing POST confirmation alert
Two key workarounds suggested were the PRG pattern, and an AJAX submit followed by a scripting relocation.
Note that if your method allows for a GET and not a POST submission method, then that would both solve the problem and better fit with convention. Those solutions are provided on the assumption you want/need to POST data.
The only way to be 100% sure the same form never gets submitted twice is to embed a unique identifier in each one you issue and track which ones have been submitted at the server. The pitfall there is that if the user backs up to the page where the form was and enters new data, the same form won't work.
There are two parts to the answer:
Ensure duplicate posts don't mess with your data on the server side. To do this, embed a unique identifier in the post so that you can reject subsequent requests server side. This pattern is called Idempotent Receiver in messaging terms.
Ensure the user isn't bothered by the possibility of duplicate submits by both
redirecting to a GET after the POST (POST redirect GET pattern)
disabling the button using javascript
Nothing you do under 2. will totally prevent duplicate submits. People can click very fast and hackers can post anyway. You always need 1. if you want to be absolutely sure there are no duplicates.
You can use replaceState method of JQuery:
<script>
$(document).ready(function(){
window.history.replaceState('','',window.location.href)
});
</script>
This is the most elegant way to prevent data again after submission due to post back.
Hope this helps.
If you refresh a page with POST data, the browser will confirm your resubmission. If you use GET data, the message will not be displayed. You could also have the second page, after saving the submission, redirect to a third page with no data.
Well I found nobody mentioned this trick.
Without redirection, you can still prevent the form confirmation when refresh.
By default, form code is like this:
<form method="post" action="test.php">
now, change it to
<form method="post" action="test.php?nonsense=1">
You will see the magic.
I guess its because browsers won't trigger the confirmation alert popup if it gets a GET method (query string) in the url.
The PRG pattern can only prevent the resubmission caused by page refreshing. This is not a 100% safe measure.
Usually, I will take actions below to prevent resubmission:
Client Side - Use javascript to prevent duplicate clicks on a button which will trigger form submission. You can just disable the button after the first click.
Server Side - I will calculate a hash on the submitted parameters and save that hash in session or database, so when the duplicated submission was received we can detect the duplication then proper response to the client. However, you can manage to generate a hash at the client side.
In most of the occasions, these measures can help to prevent resubmission.
I really like #Angelin's answer. But if you're dealing with some legacy code where this is not practical, this technique might work for you.
At the top of the file
// Protect against resubmits
if (empty($_POST)) {
$_POST['last_pos_sub'] = time();
} else {
if (isset($_POST['last_pos_sub'])){
if ($_POST['last_pos_sub'] == $_SESSION['curr_pos_sub']) {
redirect back to the file so POST data is not preserved
}
$_SESSION['curr_pos_sub'] = $_POST['last_pos_sub'];
}
}
Then at the end of the form, stick in last_pos_sub as follows:
<input type="hidden" name="last_pos_sub" value=<?php echo $_POST['last_pos_sub']; ?>>
Try tris:
function prevent_multi_submit($excl = "validator") {
$string = "";
foreach ($_POST as $key => $val) {
// this test is to exclude a single variable, f.e. a captcha value
if ($key != $excl) {
$string .= $key . $val;
}
}
if (isset($_SESSION['last'])) {
if ($_SESSION['last'] === md5($string)) {
return false;
} else {
$_SESSION['last'] = md5($string);
return true;
}
} else {
$_SESSION['last'] = md5($string);
return true;
}
}
How to use / example:
if (isset($_POST)) {
if ($_POST['field'] != "") { // place here the form validation and other controls
if (prevent_multi_submit()) { // use the function before you call the database or etc
mysql_query("INSERT INTO table..."); // or send a mail like...
mail($mailto, $sub, $body); // etc
} else {
echo "The form is already processed";
}
} else {
// your error about invalid fields
}
}
Font: https://www.tutdepot.com/prevent-multiple-form-submission/
use js to prevent add data:
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
In Codeigniter I used to call the view function after posting data. Like below;
Ex: I have a show_products() function which will display list of products. When a user add a new product I'm posting data into add_product() function. If the process is successful I will not redirect to the products page, instead load the display function inside the add_product() like this:
//Inside the add_product() function
if(success){
$this->show_products();
}
I think, there is no point of reloading the page again. Since we are already in the post function we can straight away set the view after the database insert.
However in laravel I see people redirecting after posting data.
ex:
//Inside the postProduct() function
if(success){
return Redirect::to('products');
}
I tried;
//Inside the postProduct() function
if(success){
$this->getIndex();// this is my product display function
}
but it didn't work.
Do we have a benefit by loading the view in the post function without redirecting every time?
If so how can I achieve the same thing with the laravel?
Thanks a lot!
It's not about the Laravel, instead, it's about a good or right way of doing things. In other words, it's a good programming practice to redirect to another route/page after you successfully submit a form.
Even in CodeIgniter or plain Php I do like this approach and encourage other developers to do that. So, the question is why this redirect is better than directly calling another method from the same request to show another view/page ?
This is the life cycle of the process:
You post a form to a route/action page.
You validate the submitted data and upon successful validation you insert the submitted data in to your database, otherwise you redirect back to that form with errors and old user inputs.
So. assume that, you have submitted a form and done saving the data into database successfully. After you save it you done something like this:
return View::make('...')->with('success', 'Data saved!');
In this case, your user can see the success message on the screen but what if the user, presses the f5 key from the keyboard to refresh the page (probably, accidentally), the form will be submitted to the same action again and the whole process will be repeated again.
So, if you had a redirect after form submission then, refreshing the page won't make any request to that form again.
Google search result on form resubmit on refresh., check the links, may be first one/two, you'll get better idea about the problem and the benefits of redirection after form submission.
in Codeigniter to redirect page we have redirect() function.
if(success){
redirect('products');
}
You don't have to return Redirect. The reason people use it quite often in larvel is because it's comfy.
You can return something else, eg. a view:
return View::make('home.index')->with('var',$var);
In Laravel, to redirect after doing a POST, you could return a redirect with a named route:
return redirect()->route('my-route-name');
Or if you are within the controller that has the route method you want (eg. the index method, you could do this as well:
return self::index();
How do I clean information in a form after submit so that it does not show this error after a page refresh?
See image (from chrome):
The dialog has the text:
The page that you're looking for used
information that you entered. Returning to that
page might cause any action you took to be
repeated. Do you want to continue?
I want this dialog not to appear.
This method works for me well and I think the simplest way to do this is to use this javascript code inside the reloaded page's HTML.
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
Edit: It's been a few years since I originally posted this answer, and even though I got a few upvotes, I'm not really happy with my previous answer, so I have redone it completely. I hope this helps.
When to use GET and POST:
One way to get rid of this error message is to make your form use GET instead of POST. Just keep in mind that this is not always an appropriate solution (read below).
Always use POST if you are performing an action that you don't want to be repeated, if sensitive information is being transferred or if your form contains either a file upload or the length of all data sent is longer than ~2000 characters.
Examples of when to use POST would include:
A login form
A contact form
A submit payment form
Something that adds, edits or deletes entries from a database
An image uploader (note, if using GET with an <input type="file"> field, only the filename will be sent to the server, which 99.73% of the time is not what you want.)
A form with many fields (which would create a long URL if using GET)
In any of these cases, you don't want people refreshing the page and re-sending the data. If you are sending sensitive information, using GET would not only be inappropriate, it would be a security issue (even if the form is sent by AJAX) since the sensitive item (e.g. user's password) is sent in the URL and will therefore show up in server access logs.
Use GET for basically anything else. This means, when you don't mind if it is repeated, for anything that you could provide a direct link to, when no sensitive information is being transferred, when you are pretty sure your URL lengths are not going to get out of control and when your forms don't have any file uploads.
Examples would include:
Performing a search in a search engine
A navigation form for navigating around the website
Performing one-time actions using a nonce or single use password (such as an "unsubscribe" link in an email).
In these cases POST would be completely inappropriate. Imagine if search engines used POST for their searches. You would receive this message every time you refreshed the page and you wouldn't be able to just copy and paste the results URL to people, they would have to manually fill out the form themselves.
If you use POST:
To me, in most cases even having the "Confirm form resubmission" dialog pop up shows that there is a design flaw. By the very nature of POST being used to perform destructive actions, web designers should prevent users from ever performing them more than once by accidentally (or intentionally) refreshing the page. Many users do not even know what this dialog means and will therefore just click on "Continue". What if that was after a "submit payment" request? Does the payment get sent again?
So what do you do? Fortunately we have the Post/Redirect/Get design pattern. The user submits a POST request to the server, the server redirects the user's browser to another page and that page is then retrieved using GET.
Here is a simple example using PHP:
if(!empty($_POST['username'] && !empty($_POST['password'])) {
$user = new User;
$user->login($_POST['username'], $_POST['password']);
if ($user->isLoggedIn()) {
header("Location: /admin/welcome.php");
exit;
}
else {
header("Location: /login.php?invalid_login");
}
}
Notice how in this example even when the password is incorrect, I am still redirecting back to the login form. To display an invalid login message to the user, just do something like:
if (isset($_GET['invalid_login'])) {
echo "Your username and password combination is invalid";
}
It has nothing to do with your form or the values in it. It gets fired by the browser to prevent the user from repeating the same request with the cached data. If you really need to enable the refreshing of the result page, you should redirect the user, either via PHP (header('Location:result.php');) or other server-side language you're using. Meta tag solution should work also to disable the resending on refresh.
After processing the POST page, redirect the user to the same page.
On
http://test.com/test.php
header('Location: http://test.com/test.php');
This will get rid of the box, as refreshing the page will not resubmit the data.
It seems you are looking for the Post/Redirect/Get pattern.
As another solution you may stop to use redirecting at all.
You may process and render the processing result at once with no POST confirmation alert. You should just manipulate the browser history object:
history.replaceState("", "", "/the/result/page")
See full or short answers
You could try using AJAX calls with jQuery. Like how youtube adds your comment without refreshing. This would remove the problem with refreshing overal.
You'd need to send the info necessary trough the ajax call.
I'll use the youtube comment as example.
$.ajax({
type: 'POST',
url: 'ajax/comment-on-video.php',
data: {
comment: $('#idOfInputField').val();
},
success: function(obj) {
if(obj === 'true') {
//Some code that recreates the inserted comment on the page.
}
}
});
You can now create the file comment-on-video.php and create something like this:
<?php
session_start();
if(isset($_POST['comment'])) {
$comment = mysqli_real_escape_string($db, $_POST['comment']);
//Given you are logged in and store the user id in the session.
$user = $_SESSION['user_id'];
$query = "INSERT INTO `comments` (`comment_text`, `user_id`) VALUES ($comment, $user);";
$result = mysqli_query($db, $query);
if($result) {
echo true;
exit();
}
}
echo false;
exit();
?>
I had a situation where I could not use any of the above answers. My case involved working with search page where users would get "confirm form resubmission" if the clicked back after navigating to any of the search results. I wrote the following javascript which worked around the issue. It isn't a great fix as it is a bit blinky, and it doesn't work on IE8 or earlier. Still, though this might be useful or interesting for someone dealing with this issue.
jQuery(document).ready(function () {
//feature test
if (!history)
return;
var searchBox = jQuery("#searchfield");
//This occurs when the user get here using the back button
if (history.state && history.state.searchTerm != null && history.state.searchTerm != "" && history.state.loaded != null && history.state.loaded == 0) {
searchBox.val(history.state.searchTerm);
//don't chain reloads
history.replaceState({ searchTerm: history.state.searchTerm, page: history.state.page, loaded: 1 }, "", document.URL);
//perform POST
document.getElementById("myForm").submit();
return;
}
//This occurs the first time the user hits this page.
history.replaceState({ searchTerm: searchBox.val(), page: pageNumber, loaded: 0 }, "", document.URL);
});
I found an unorthodox way to accomplish this.
Just put the script page in an iframe. Doing so allows the page to be refreshed, seemingly even on older browsers without the "confirm form resubmission" message ever appearing.
Quick Answer
Use different methods to load the form and save/process form.
Example.
Login.php
Load login form at Login/index
Validate login at Login/validate
On Success
Redirect the user to User/dashboard
On failure
Redirect the user to login/index
So I have a web app that i'm working on with a form that requires all of the fields to be populated before submitting. If you try to submit the app without a field being populated, it loads the page again with the errors. Once you fill all the fields in and click submit, it does a redirect to the same page and shows a message which is generated from flashdata. See simplified example below.
Welcome controller:
function show_view()
{
$this->load->view('form');
}
function process_form()
{
// make the 'quality' field required
$this->form_validation->set_rules('quality', 'Quality', 'required');
if($this->form_validation->run() == FALSE) //if the fields are NOT filled in...
{
echo form_error('quality');
$this->load->view('form'); //reload the page
}
else // if the fields are filled in...
{
// set success message in flashdata so it can be called when page is refreshed.
$this->session->set_flashdata('message', 'Your rating has been saved');
redirect(welcome/show_view);
}
}
Now to illustrate my issue, lets say I'm on the 'home' view and I navigate to the 'form' view. If i populate the 'quality' field and click submit, i get redirected back to the 'form' view, with a success message. If i click the back button on the browser, it takes me back to the 'home' view. EVERYTHING WORKS AS EXPECTED
Now lets say i'm on the 'home' view and I navigate to the 'form' view. If i click the submit button without populating the 'quality' field, the 'form' view is reloaded again and it displays the error message. If i then populate the 'quality' field and click submit, i get redirected back to the 'form' view with a success message. The problem is, if i click the back button on the browser, it now takes me back to the form page with the error, and I have to click the back button again to get back to the 'home' view.
What is the best coding practice so that if a user submits the form with errors, it will display the errors, and if they fix the errors and submit the form again it will display the success message and if they click back on the browser, it will take them back to the 'home' view??
The problem is that you're using two separate functions to do form handling. The form validation class docs don't really explain it well, and it took me awhile to realize it but the form_validation->run() returns false if there is an error, but also if it is a GET request, and subsequently accounts for the GET request in the related functions like the form_error(), and validation_errors(), set_value(), etc.
The best practice in CI (and in general) is to do this:
class Welcome extends CI_Controller{
function home(){
$this->load->view('home');
}
function form()
{
// make the 'quality' field required
$this->form_validation->set_rules('quality', 'Quality', 'required');
// If the fields are NOT filled in...
// or if there isn't a POST! (check the Form_validation.php lib to confirm)
if ( $this->form_validation->run() === FALSE)
{
// This form_error() function actually doesn't do anything if there
// wasn't a form submission (on a GET request)
echo form_error('quality');
$this->load->view('form'); // load or reload the page
}
else // if the fields are filled in...
{
// set success message in flashdata so it can be
// called when page is redirected.
$this->session->set_flashdata('message', 'Your rating has been saved');
redirect('welcome/home','location', 303);
exit;
}
}
then in the view have the form action="welcome/form"
Basically all of the form error functions and all the stuff related to form validation have checks to see if the form validator actually ran... here is an example from the form_error function in the form helper file
function form_error($field = '', $prefix = '', $suffix = '')
{
if (FALSE === ($OBJ =& _get_validation_object()))
{
return '';
}
return $OBJ->error($field, $prefix, $suffix);
}
When their isn't a POST, it shows as normal, and has the natural page flow you are looking for.
Unrelated to the question, but confusing/noteworthy about the form validation class... if you use the filters like xss_clean, prep_url, etc. in the parameters field, it actually repopulates the $_POST array for you, so you don't really need to do anything extra.
Sometimes it's worth taking a look at the internals of the CI source, there's some clever stuff in there which isn't entirely obvious.
What I expect is for the form to redirect me to a resource listing page, where resource is the entity the user was submitting initially.
If the user is adding a new entry to a resource, they expect to see the entry in the listing once the form has been submitted successfully.
If the form is on the same page, you should still do a location based redirect instead of a http refresh. The status code for this use case is 303 See Other.
via Wikipedia HTTP 303 Status Code
Here is what I would do given your scenario.
function home(){
$this->load->view('home');
}
function show_view()
{
$this->load->view('form');
}
function process_form()
{
// make the 'quality' field required
$this->form_validation->set_rules('quality', 'Quality', 'required');
if($this->form_validation->run() === FALSE) //if the fields are NOT filled in...
{
echo form_error('quality');
$this->load->view('form'); //reload the page
}
else // if the fields are filled in...
{
// set success message in flashdata so it can be called when page is redirected.
$this->session->set_flashdata('message', 'Your rating has been saved');
redirect('welcome/home','location', 303);
exit;
}
}
I'm using Symfony for a while and I think that Symfony's solution is optimal. The way it works is that you have routings (I think that CI has routings too: CI routings) and in your controller you can do something like this in your "create" method:
if the form is valid
set flash notice message
redirect to (your homepage or something else defined in your routing file)
else
set flash error message
set the current view to form
Your form's action is the same controller with the "create" action (which can be only reached via a POST request). The form which you can reach with GET requests is the "new" method. So if you click submit on your form you go to the create method, but the new method generates your form for the first time. If your form does not validate you stay there with flash error messages. If you click back you get a new form, but if the form validates your action (method) redirects to a custom page you set before in the if statement above.
This method works with ajax too, you can check in your action if the request is an XHTTP one, you just return if the form validates or not and you can handle things in javascript. I think that this is the best way to handle forms and if your user does not have javascript enabled he can still use the "standard" way. And by the way: "create" and "new" uses the same template (view). I hope that i made things clear.
The only reliable way to tell the browser to ignore/remove pages in its history is with the javascript command:
location.replace(url);
this does a client-side redirect but replaces the current location in your browser history. Or alternatively not to going to a new page at all (ajax call).
If you use POST as the method in your form they will get an error saying they have to resubmit information to the server to go back, which will scare most people off from using the back button.
You could use a nonce pattern where you generate a timestamp or other unique id, put it in the session and a hidden field in your show_view function when you create the form and then check for a match it on your process function, and remove it from the session if there is a match. That way if they try to submit the same form twice (by clicking the back button) you can detect it by seeing there is not a match and redirect them to the errorless show_view or home page or wherever else you want.
You'll also want to make sure your expires and cache-control headers are forcing the web browser to hit the server everytime vs just using its local cache. http://www.web-caching.com/mnot_tutorial/notes.html#IMP-SERVER
For bettor or worse, most web sites ignore the back button issues such as these
The DOM window object provides access to the browser's history through the history object. It exposes useful methods and properties that let you move back and forth through the user's history, as well as -- starting with HTML5 -- manipulate the contents of the history stack.
https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
Another thing would be to submit the form with ajax! and populate the errors or success message based on response...(XML,JSON..) of course this is not exactly what you were looking for but it has a lot of advantages in user experience which is what you are trying to improve.
If at all possible avoid a redirect and have the page show the same content as where its being redirected. That way browsers won't count multiple submissions as different pages.
Also the new HTML5 javascript has history state change or whatever its called. So you can define in your program how the site should behave to page changes through the back button and ... soon you will see a lot of back buttons integrated into the web GUI as well.
The easiest way to do what you're proposing is to submit the form values to your PHP validator using an HTTPRequest (AJAX) and then show the errors using JavaScript. This way you won't have to do any redirecting, and the back button will still take you home.
If you insist on using redirections, I have a few ideas in mind, but none of them are elegant. Perhaps someone else has an idea for this?
Although I really would recommend using AJAX form submission as a solution for this problem.
As far as I know - and can find - there is no reliable way to catch the history back event, and all the solutions are Javascript based so you might as well build an AJAX form.
I'd say the only possible non-javascript solution would be either an iframe (which nobody likes), or what BraedenP suggests.
Personally, if you really want this functionality, I'd build an AJAX form and just not have it work this way for non-javascript users (they should be used to having a slightly less streamlined experience).
It's always good practice to add a breadcrumb trail or back button on your page, so this could help as well.
I.e. would you recommend me to use one controller method like this:
function save()
{
if(!is_bool($this->input->post('')))
{
$post_data = $this->input->post('');
$this->mymodel->save($post_data);
}
$this->load->view('myview');
}
Or would you recommend writing it using two methods?
function save()
{
if(!is_bool($this->input->post('')))
{
$post_data = $this->input->post('');
$this->mymodel->save($post_data);
}
redirect('controller/method2')
}
The redirect is the crucial difference here. It prohibits resubmissions from update for example.
How do you do it? Is there another better way?
You should always redirect on a successful form post.
You should always redirect on a successful form post.
Absolutely. For anyone wondering why this is the case, here are a couple of the reasons:
Avoid "duplicate submissions". Ever had that when you innocently click refresh or hit the back button and wham, everything has resubmitted?
Being friendly to bookmarks. If your user bookmarks the page, presumably you want them to return where they created it, rather than a blank form (a redirect makes them bookmark the confirmation/landing page.
Further reading:
http://en.wikipedia.org/wiki/Post/Redirect/Get
As Aren B said, redirection is a good idea, but what I would change in your code is that validation of the post data should be done with the form validation functionallity. It is not only more reauseable but the code will get shorter.
If you want to handle AJAX requests, you would need to return something else than a via or a redirection.