Fog Creek Software
g
Discussion Board




HTML forms and back button in dynamic apps

I am quite curious to know what you guys do use to manage the following scenario:

In a dynamic web app, I do not want the user to be able to view a page with a form he saw already.

This is meant to avoid having them repost the same data twice or go back to a former screen in their cache and say "hey, this isn't updated"... (they aren't very aware of web stuff).

So, I decided to set expiration headers, <META> and whatever to have the pages stay uncached.

Most of the navigation of the app is done through <FORM>'s <SUBMIT> buttons.

This works well but  there is always a user hitting the "back" button, leading to "this page has expired, you can do a refresh on it" etc. If they refresh, they get a valid screen.

Of course, the message is clearly a nuisance (even if I understand why it's there).

This whole thing leads me to a dilemnna:

a) I remove the expiration headers and they get bad state data (risking really annoying updates through outdated forms)

vs

b) I leave the headers and the back button doesn't work and they keep banging on it, telling me the app is not working properly.

As a solution, a friend of mine told me that I should be using redirects to views as answers, so that when users hit the back button, they get cached content. I do not want to use those redirects because they put quite many pingpongs between the client and the server.

I am using servlets as technology and the "architecture" is quite clean. I am pleased with what I've done but this "back  button" thing drives me mad without any clue on how to proceed properly.

Any advice ? Thanks in advance !

Phil
Wednesday, December 3, 2003

Hitting back in my application also causes weird results.

I can tell when the user hits back, then does something in the application that loads a new page, so it does its best and tells the user to use my navigation buttons instead. This isn't perfect either, so for some customers the application pops up in a new window with the back button removed.

Dorn
Wednesday, December 3, 2003

Here is an old thread

http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=90429&ixReplies=14

You should really try to support the back button, otherwise it drives the users nuts.

DJ
Wednesday, December 3, 2003

The back-button problem is definitely a huge one.  Like Jakob Nielson says, that's the one button most users *do* understand.

Mostly, I try to keep each page self-contained to avoid the issue altogether.  I try to avoid web applications where a *sequence* of pages is necessary so that there are no "wrong" pages to be on.

When that's not possible, I do a couple of things.  First, I keep each page self-contained to a large extent, even if it's part of a sequence in pages.  I have each page submit to itself, do the necessary error-checking and database work, store the URL of the next "correct" page into a persistant variable (cookie, Session, whatever) and then redirect the user to the next page. 

That persistant variable comes in handy because you can put code at the top of each page (before any other processing) that checks the current URL against the "correct" URL, and forwards them to the appropriate page if there's a mismatch.  So if they hit the back button or otherwise dick around, they can be redirected to the right place.

It's like the first week of kindergarten.  They pin your bus number onto your shirt, so that if you get onto the wrong bus you can easily be spotted and placed on the correct one.  ;-)

John Rose
Wednesday, December 3, 2003

one of the most apt analogies I've heard.  Bravo!

chuck
Wednesday, December 3, 2003

Thanks!  I should definitely thank you guys for it, because I never thought of it until I typed that reply.  I'll be able to use that in the future when I'm explaining things to bosses and clients.

John Rose
Wednesday, December 3, 2003

I'm not sure if I completely understand the situation, but I don't think you should worry about using redirects.  HTTP 1.1, which virtually all modern browsers and servers use, allows multiple requests/responses within a single connection. So the overhead of using a redirect is very small - just the cost of generating the 302 "Moved temporarily" response.

Abe Fettig
Wednesday, December 3, 2003

Well, it was my understanding that HTTP/1.1 allows multiple requests ANDTHEN multiple responses in a single transaction.

A redirect causes the browser to ping pong and that is unescapable.

With HTTP/1.1:
BEGIN CONNECTION 1
Browser requests /index.html
Browser sends EOF
Server sends contents of /index.html
Server sends EOF
END CONNECTION 1
Browser parses index.html
BEGIN CONNECTION 2
Browser requests header.gif
Browser requests leftnav.gif
Browser requests background.gif
Browser requests main.css
Browser requests main.js
Browser sends EOF
Server sends content of all above files
Server sends EOF
END CONNECTION 2

If the Server waited around whle the browser parsed index.html in case the browser was going to make another request, then the real world performance of the server would be abysmal(sp?). 

So therefore, even with HTTP/1.1, a redirect will still cause an extra connection and request.

Furthermore, REDIRECTS DO NOT SOLVE THE PROBLEM OF THE BACK BUTTON.  The user can just pull down the back menu and skip 2 pages back.

Richard P
Wednesday, December 3, 2003

"In a dynamic web app, I do not want the user to be able to view a page with a form he saw already."

Why not? As a user, I ought to be able to navigate all over the web app and if I hit the back button, the page had better look exactly like it did when I left it. Think Amazon.

All this talk about forcing a particular page to display because that's how it's supposed to be in the sequence is just wrong. It's really because it's easier to force the implementation model of your app on the user than it is to design correctly for the user in the first place.

Here's another analogy: Suppose I want to write a letter to someone. I should be able to write the letter, put a stamp on the envelope and write the address on the envelope in any order I want. If I leave one of these tasks out, the system (post office or recipient) will handle it appropriately.

The user should always be in control!

Inteaction Architect
Wednesday, December 3, 2003

At least no one has asked how to disable the back button! I get that stupid request all the time...

Interaction Architect
Wednesday, December 3, 2003

Agreed Interaction Architect.  Lack of control = frustration.

Who wants to frustrate their users?  Seems better to avoid this situation even if it means extra work.

Scot Doyle
Wednesday, December 3, 2003

--
Furthermore, REDIRECTS DO NOT SOLVE THE PROBLEM OF THE BACK BUTTON.  The user can just pull down the back menu and skip 2 pages back.
--

I think thats the case with META refreshes, but not with HTTP redirects.  You can't get back to the page that redirected you, since there is no page there.  Just a small HTTP respnse telling you to redirect.

But if you're using META refreshes to implement this, you're correct.  You will have exactly the problem you mention above.

Andrew Hurst
Wednesday, December 3, 2003

What's more frustrating for a user that can barely browse the web as it is? Having a back button that causes the application to behave improperly or not have a back button at all?

I don't mind letting the user view a previous page, but in this particular application the user is providing information on each page that determines which pages come next. Calculations happen in the background every time you navigate between pages. If they want to go back in the process, they use my back button, which will figure out where to take them.

If a user clicks the browser back button, then clicks my continue button, they have jumped around without the proper calculations being done. I can detect this and send them back to the appropriate place, but that's annoying for the user. (The server knows which page the user should be on, and if they post from a page with the wrong id, it figures out what to do)

I've watched users use my continue button to go to the next page. They then click the browser back button, make a change, and click the browser forward button. Obviously that is going to break things too. Again, it's not really broken, but the changes they made before using their browser forward button are lost. Of course, depending on their browser they will get that message about posting to a form. They have no idea what that means.

This application is sold to end users and used on an intranet. If the customers ask if I can hide the back button, I do it for them. This has the added bonus of the customer thinking they helped me out by suggesting that, which makes them feel good for some reason.

Dorn
Wednesday, December 3, 2003

I definitely agree that the need to disable/circumvent the back button should be avoided whenever possible, because it really does break the web-browsing paradigm they're used to.

In addition to the redirection method I listed above, there's also the Server.Transfer method in newer versions of IIS in "classic" ASP... not sure about ASP.NET, or equivalencies in other languages.  Server.Transfer sort of works like an HTTP redirection, but the browser never gets "ping-ponged" around because it's all handled server-side.  This is obviously more secure, as well, since a user's web browser can ignore a redirection request.  :P

Consider the following two scenarios where the user *ought* to be on page 2, but hits the back button to try and go to page 1.

Scenario 1 (using HTTP redirection):
User's browser requests Page 1
Code on server determines they ought to be on Page 2
Server tells browser to redirect to Page 2
User's browser requests Page 2
Server serves up Page 2

Scenario 2 (using Server.Transfer or equiv.)
User's browser requests Page 1
Code on server determines they ought to be on Page 2
Server.Transfer("page2.asp")
Server serves up Page 2

So scenario 2 saves an HTTP round-trip and is more seamless for the user since there's no delay.  It's still a bit of a deviation from the standard web paradigm, since the browser's URL bar will still say "page1.asp" even though the server parsed, executed, and served up page2.asp...

Obviously this is a kludgy situation no matter how you look at it, so you want to avoid it for sure.  But it really is necessary in rare occaisions...

John Rose
Wednesday, December 3, 2003

Dorn, I often get around a missing back button by right-clicking on the web page and choosing 'back'.  I'm not saying that it is easy to develop for people like me:-)  I'm only telling you how I feel as a user.  But I may not match the 'target user profile'.

Scot Doyle
Wednesday, December 3, 2003

I hate webapps that don't handle the Back button gracefully, especially when I know it can be done.

Like a poster above said, try to keep pages as self-contained as possible, so they don't rely much if at all on what was happening before or after.  It also helps if you can reduce the need for the user to press 'Back' in the first place, by doing things like displaying previously entered data on the page so they won't have to go back to check if they entered something right.

Still, there are some cases where the nature of the activity requires a series of steps that must be applied as a unit at the end.  This requires you to defend against three common scenarios:

1) The Back button is pressed before the sequence of actions is completed.

2) The Back button is pressed after the sequence of actions is completed, bringing them back to one of the pages within the sequence.

3) The user is within the sequence of actions, then jumps over to another page on your site that has nothing to do with the sequence.

For (1), you keep track of the actions performed.  This is where the Command pattern can help; each page submission is encapsulated in a Command object which gets pushed onto a queue that you maintain until the final step is submitted.  When a user jumps back, you undo the actions that came after the point where they jumped, removing the Command objects as necessary.  Preferably you don't actually make any permanent changes to the database until the final submission is received, so your undo will be fairly simple.  On the final submission, you just process the list of Commands that was built up and apply the changes to your back-end storage.

For (2), unless you can figure out an intelligent thing to do, it is likely the only feasible option is to redirect them to a page where they are supposed to be.

For (3), you are really concerned only if the user jumps back into one of the pages within the sequence.  If they do that, and they pick up where they left off, then you should try to do the same thing on your end and let them continue seamlessly.  If they jump to a step that was prior to the one they left off, follow the technique for (1) to undo the actions that came afterwards.

T. Norman
Wednesday, December 3, 2003

For pages like this I use the struts workflow extension.

http://www.livinglogic.de/Struts/

Michael Koziarski
Thursday, December 4, 2003

I've built some non-trivial web-applications and I get around this problem by removing the toolbar completely. The logon page opens a new window, without all the normal IE baggage (menu, toolbar, context-menu, etc).

I can get away with this, as it is a web application, not a site. That is, it works, from the User's point of view, just like a normal application, rather than a website.

I think this is valid, as there is absolutely no User expectation that the system should behave like a website. It is a new Business Application to them, and the fact that it happens to be deployed over HTTP to their browser is not exactly top of their list of priorities.

Steve Jones (UK)
Thursday, December 4, 2003

Whoa! 3 of the 5 'benefits' of using the struts workflow extensions begin with the words "Prevent the user from ...".

Let me guess, it's so much _easier_ to throw a system together and slap a UI on it than it is to go anywhere near some user task and analysis for the interface design. Right?

Interaction Architect
Thursday, December 4, 2003

Thanks for all the info, I'll try to figure out a strategy that will not lead me to recode all of the app :-)

Phil
Thursday, December 4, 2003

"I've built some non-trivial web-applications and I get around this problem by removing the toolbar completely. The logon page opens a new window, without all the normal IE baggage (menu, toolbar, context-menu, etc)."

I hope you still have code in there to handle the Back button issues, because disabling browser controls won't always work.  If they aren't using IE, they may set their browser settings to prevent applications from hiding controls, or they may do what I do and use a local proxy server that strips out the commands that do things like that.

There are also malicious users who will do things like save a web page to their hard drive and try to submit it out of sequence.

Unless you are speaking of an in-house application where you can control the browser that people use, you still have some work to do in order to handle the Back button, even if it is only to show an error message.

T. Norman
Thursday, December 4, 2003

Yeah, there's extra code to handle lots of keyboard shortcuts, etc.

Fortunately, it is indeed an in-house Intranet application where the installation is IE6+ and locked down.

The Users will never be able to customize their browsers.

When it's launched on the Extranet/Internet next year, it'll be a requirement that the User only uses IE6+, so we can still apply these modifcations to the browser.

Saving and later submitting the pages will not work as the security scheme will detect and prevent this behaviour.

Steve Jones (UK)
Thursday, December 4, 2003

What's the living equivalent of turning in your grave? Because that's what Tim Berners-Lee must be doing.

John Topley (www.johntopley.com)
Thursday, December 4, 2003

Next time, I'll do an applet (I am serious).

Well, other problems will show up - like having W2K giving a BSOD when using JDK1.3 and JDK1.4.1 by the side... incredible.

Phil
Thursday, December 4, 2003

>"Saving and later submitting the pages will not work as the security scheme will detect and prevent this behaviour."

I meant saving and submitting the page while the session is still active, so it can be submitted out of sequence.  Unless your disabling mechanism can also prevent them from saving pages.

T. Norman
Thursday, December 4, 2003

Also, if I remember correctly, the amazon shopping cart handles the back button correctly and also lets me jump to any page from within the checkout sequence without forcing back into the checkout sequence.

As a user, this is one reason i expect apps to handle these cases.  Again, I am speaking only as a user.

Scot Doyle
Thursday, December 4, 2003

*  Recent Topics

*  Fog Creek Home