Forms working as expected most of the time but occasionally they simply clears

84 views
Skip to first unread message

Lennon

unread,
Sep 14, 2011, 12:34:45 AM9/14/11
to web2py-users
I have a few forms in a web2py shopping cart that I built from
scratch. Most of the time the forms are working fine but once in
awhile on submission a form will neither submit and redirect to the
next page of the cart nor return any form errors as it usually does
when there is a form error.

Instead it simply refreshes the page and clears the form. What's
really frustrating about this bug is that the same user will have this
bug and when they try again with the same browser and same data it
will work fine.

In fact, none of my team has been able to reproduce it but three of
our users have reported it so I'm inclined to think something is
wrong.

One thing the forms all in common is that they all add session as an
argument for form.accepts:

if form.accepts(request.vars, session):

Perhaps if something was screwy in my session it might cause this
behavior? Although when I looked in the gluon/sqlhtml web2py file it
didn't seem to use session for much of anything.

The various forms and models are all very long so before posting all
of that code, I was wondering if anybody simply had some thoughts on
what might be causing this and/or could point me in the right
direction.

I'll be happy to post any part of the code that would help shed some
light on the matter. Let me know, thanks.

Massimo Di Pierro

unread,
Sep 14, 2011, 12:44:17 AM9/14/11
to web2py-users
Is it possible they had two windows open on the same form? Passing the
session to accepts(...) uses a mechanism to prevent double form
submission that assume once a form is open, it is only opened one
(within the session) until it is submitted.

Lennon

unread,
Sep 14, 2011, 9:16:37 PM9/14/11
to web2py-users
Thanks you! Thanks to this info I was able to recreate the exact form
clearing problem by loading another instance of the form in another
tab/window.

I have taken out the session from form.accepts in those forms and now
everything is fine.

Can anybody forsee any problems with my removing that?

~Lennon

On Sep 14, 12:44 am, Massimo Di Pierro <massimo.dipie...@gmail.com>
wrote:

Cliff

unread,
Sep 14, 2011, 10:36:41 PM9/14/11
to web2py-users
Double submits can happen.

Anthony

unread,
Sep 14, 2011, 10:47:55 PM9/14/11
to web...@googlegroups.com
Also, cross-site request forgery attacks: https://www.owasp.org/index.php/Top_10_2010-A5

Anthony


On Wednesday, September 14, 2011 10:36:41 PM UTC-4, Cliff wrote:
Double submits can happen.

On Sep 14, 9:16 pm, Lennon <lpr...@hotmail.com> wrote:
> Thanks you!  Thanks to this info I was able to recreate the exact form
> clearing problem by loading another instance of the form in another
> tab/window.
>
> I have taken out the session from form.accepts in those forms and now
> everything is fine.
>
> Can anybody forsee any problems with my removing that?
>
> ~Lennon
>
> On Sep 14, 12:44 am, Massimo Di Pierro <massimo....@gmail.com>

Lennon

unread,
Sep 15, 2011, 2:03:24 PM9/15/11
to web2py-users
In that case does anybody have any ideas about how to gracefully
handle this Session problem without removing session from
form.accepts?

Anthony suggested having a javascript pop-up when the session times
out but don't web2py sessions not timeout while the browser remains
open be default? It seems like the cause must be the double form or
something else.

Anthony

unread,
Sep 15, 2011, 2:14:34 PM9/15/11
to web...@googlegroups.com
On Thursday, September 15, 2011 2:03:24 PM UTC-4, Lennon wrote:
In that case does anybody have any ideas about how to gracefully
handle this Session problem without removing session from
form.accepts?

Anthony suggested having a javascript pop-up when the session times
out but don't web2py sessions not timeout while the browser remains
open be default?

If the browser is open but not sending any requests back to the server, the server has no way of knowing it is still open, so the session can still time out.

Anthony 

Lennon

unread,
Sep 15, 2011, 2:36:30 PM9/15/11
to web2py-users
So in that case it looks to me like web2py's timeout defaults to 3600
seconds (1 hour).

If a user had a form opened for over an hour and then attempted to
submit the form, would that cause the form to be returned without
errors just like the double form window would cause?

If so, that's probably what was happening as that seems much more
likely than having two form windows open.

If that is the case, starting a JS timer on each page that alerted and
redirected after an hour would solve this problem correct?

Anthony

unread,
Sep 15, 2011, 4:51:24 PM9/15/11
to web...@googlegroups.com
Actually, now that I think about it, by default, web2py sessions don't expire (except that the browser will expire the cookie at the end of the browser session). There is an auth setting that expires logins, but if your form page requires a login and the login had expired, I would expect the user to get redirected to the login page instead of the form page simply reloading. If you're using something like sessions2trash.py to expire sessions, that could cause the session to expire (i.e., get deleted) on the server side.

Regardless of whether there's a session expiration problem, there could also be a problem with opening the form in multiple tabs/windows. I suppose there are workarounds in that case, but it depends on what you want to happen -- should the user be allowed to submit the form from any and all open windows, just the first window, just the most recent window (which is the default behavior)?

Anthony

On Thursday, September 15, 2011 2:36:30 PM UTC-4, Lennon wrote:
So in that case it looks to me like web2py's timeout defaults to 3600
seconds (1 hour).

If a user had a form opened for over an hour and then attempted to
submit the form, would that cause the form to be returned without
errors just like the double form window would cause?

If so, that's probably what was happening as that seems much more
likely than having two form windows open.

If that is the case, starting a JS timer on each page that alerted and
redirected after an hour would solve this problem correct?

Lennon

unread,
Sep 15, 2011, 6:29:04 PM9/15/11
to web2py-users
I guess ideally they should be able to submit from either but if that
opens the app up to double submission than the most recent is fine as
long as I have a way to handle the old form gracefully as far as user
experience is concerned. I'm open to ideas.

Anthony

unread,
Sep 15, 2011, 10:31:21 PM9/15/11
to web...@googlegroups.com
On Thursday, September 15, 2011 6:29:04 PM UTC-4, Lennon wrote:
I guess ideally they should be able to submit from either but if that
opens the app up to double submission than the most recent is fine as
long as I have a way to handle the old form gracefully as far as user
experience is concerned.  I'm open to ideas.

If there were two different forms in two different windows, I don't think that would be a double submission risk because each form could still only be submitted once (i.e., in order to submit the second form, the user would still have to manually fill it out and submit it -- there would be no danger that the same form data could be submitted twice). If you want to allow that, you would need to do something to ensure the name of the _formkey stored in the session is unique for each version of the form, so when a new form is created, it doesn't overwrite the value of the _formkey in the session but simply adds a new one. When a new form is created, something like the following is added to the session:

_formkey[form_name]='the_form_key' 

The problem is, by default, form.accepts() creates a standard form name (which is added to the form as a hidden field). Every time the form is created, the name will be the same, so _formkey[form_name] will be the same and will therefore get overwritten in the session. To avoid this, I suppose you could give the form a unique name every time it is created -- that should result in a separate session entry for each version of the form. When a form is submitted, you would then have to check request.vars for the _formname, and if found, assign that as the current form name so it will find the matching session key. Something like:

import uuid
formname=request.vars._formname or uuid.uuid4()
if form.accepts(request,session,formname=formname):
    etc.

Of course, I may be overlooking something, but I think something along those lines would work.

Anthony



Reply all
Reply to author
Forward
0 new messages