Confirm Form Resubmission Error/Document Expired (Form, Browser Back/Forward Buttons)

Hello,

I am new to Phalcon and would like to know if there is an existing way of handling Back/Forward buttons on form and cache errors that are shown in the browser? How do you deal with this in your code?

In Chrome, I often see "Confirm Form Resubmission, ERR_CACHE_MISS, [...], Press the reload button to resubmit the data needed to load the page."

In Firefox, I often see "Document Expired, This document is no longer available. The requested document is not available in Firefox's cache."

If I I refresh the page, I am asked if I authorize the browser to re-submit the form information to display the page.

In other frameworks such as Laravel I don't have that problem. I think they store form data in the session to bypass the problem. I am not an expert so I might be wrong on how they do it. But I know I don't see this error that could scare some users if they play with the browser back/forward buttons around forms.

Thank you.

edited Feb '16

You could try to add a redirect after you submit your form with the following code in your controller:

if ($this->request->isPost()) {
    /** do some logic */
    $this->response->redirect("somecontroller/someaction");
    $this->response->send();
    exit;
}

However this will cause your volt fields to lose their values, you can also implement CSRF protection to prevent the form from being able to submit twice.

In your VOLT template:

{{ hidden_field(security.getTokenKey(), 'value' : security.getToken()) }}

In your controller:

if ($this->request->isPost() && ) {
    if ($this->security->checkToken()) {
        /** Check passed, the request is guaranteeded to be unique */
        /** Add any other logic here */
    }
}

This is my concern, with such redirect, field values will be lost. If form is filled correctly I think it should be fine. However if there are form errors, I have to store the data somewhere (i.e. session) to be able to display the values after a redirect.

Any other options?

Thank you!

You could try to add a redirect after you submit your form with the following code in your controller:

if ($this->request->isPost()) { /* do some logic / $this->response->redirect("somecontroller/someaction"); $this->response->send(); exit; }

However this will cause your volt fields to lose their values, you can also implement CSRF protection to prevent the form from being able to submit twice.

In your VOLT template:

{{ hidden_field(security.getTokenKey(), 'value' : security.getToken()) }}

In your controller:

if ($this->request->isPost() && ) { if ($this->security->checkToken()) { /* Check passed, the request is guaranteeded to be unique / /* Add any other logic here / } }

Session flash messages might be a good solution for this. You can implement them like this:

In your boostrapper:

use Phalcon\Flash\Session as FlashSession;

// Set up the flash service
// Note: you must already have a session initialized
$di->set('flashSession', function () {
    return new FlashSession();
});

In your controller:

$this->flashSession->success("Some message");

In your VOLT:

{{ flashSession.output() }}

Note: all content in flash messages are un-escaped, thus combining it with user input could lead to an XSS vulnerability, you can sanitize is like this:

$this->flashSession->success(htmlspecialchars("The value '$dangerous_input' is not allowed"));

Check out Flashing Messages on the docs for the full documentation on how to use them.

edited Feb '16

So you are suggesting I use flash in order to store validation messages as well as form data (my main concern), and display values in the form?

I didn't think flash was meant to store form data, based on the doc. I am sure there is another way.

Perhaps I did not explain my problem well. I am sure I am not the only one thinking about fixing this form/browser cache problem since this is really not user friendly and to my knowledge, most php frameworks handle this without any extra code.

Just to make sure I was clear, here's how to reproduce the problem easily:

  • Go to https://vokuro.phalconphp.com/session/signup
  • Submit the form twice (empty or with invalid values) - Not double click, submit it once, when the page reloads with the errors, submit it again
  • Press the browser back button (you will see the browser cache error)
  • Press the browser forward button (you will see the browser cache error)
  • Refresh the page (you will be asked to re-submit the form)

Thank you.

Session flash messages might be a good solution for this. You can implement them like this:

In your boostrapper:

use Phalcon\Flash\Session as FlashSession;

// Set up the flash service // Note: you must already have a session initialized $di->set('flashSession', function () { return new FlashSession(); });

In your controller:

$this->flashSession->success("Some message");

In your VOLT:

{{ flashSession.output() }}

Note: all content in flash messages are un-escaped, thus combining it with user input could lead to an XSS vulnerability, you can sanitize is like this:

$this->flashSession->success(htmlspecialchars("The value '$dangerous_input' is not allowed"));

Check out Flashing Messages on the docs for the full documentation on how to use them.

edited Jul '16

i'm getting Failed to load resource: net::ERR CACHE MISS

edited Jul '16

after 3 days now I've successfully found the solution, its my chrome who's making the problem here's the fix http://www.deskdecode.com/errcachemiss/