Ok, so now the user gets an error, clicks "ok" and hits "submit" again to see if he gets an error again. Form gets sent again and we have double record in the database.
To prevent it we have secured the actions by using the session token. So it looks like this:
public function executeForm() { $this->getUser()->setAttribute('formToken',$sometoken); } public function executeAjaxAction() { if($this->getUser()->hasAttribute('formToken')) { //its the first time the user hit submit button $this->getUser()->getAttributeHolder()->remove('formToken'); // here the form is processed, saved to db and the callback is sent // depending on the result; if operation failed recreate the token } else { // there's no token in the session - the form page wasn't reloaded // and double submit occured; we can return success callback here // as we are sure that the record was created before } }
As you can see, it's very simple solution. It will work for regular html forms as well, as the "back" button makes the browser use the cache and a new token won't be generated.
The problem is, that sometimes it takes 30 seconds for "connection failure" message to appear. In that time user most likely will hit the F5 button, fill the form again... and add a duplicate record! The token protection won't work because page is refreshed. There's no way we can tell if the submitted form is a duplicate because it has input and text fields which can be filled with different words in the same context. Time blockade is not an option because sometimes users need to add few entries one after another via the same form.
So far we couldn't get around that problem. If you have any ideas, feel free to comment.
No comments:
Post a Comment