[whatwg] html5 state handling: overview and extensions
Mike Wilson
mikewse at hotmail.com
Mon Jun 15 06:33:22 PDT 2009
INTRODUCTION
HTML5 provides a number of constructs to transfer and manage
application state. In this post I attempt to classify these
constructs in a consistent manner to identify what kinds of state
management is taken care of, and what is not. My goal is to
discuss the uncovered areas to see if we can address them with
suitable additions to HTML5.
DEFINITIONS
State
To simplify this overview I limit myself to only addressing
internal state that the application stores to keep track of the
user's interaction with it, and that isn't directly accessible by
the user.
This means f ex that hidden input fields are included in this
overview (as these usually represent some internal state) but
editable input fields are not (as these correspond more to page
parameters than page state). I know this distinction may not be
perfect, and at some point we might want to include the other
parts, but I think it is good to start out with these
restrictions.
State can be stored in many different ways, and many different
things can be regarded as state, so consider the below scenario
to understand what I regard as state in this post:
- a user makes some navigation action that makes the browser
navigate to, and request http://host/page1
- when returning the response for page1, the server may include
some state ("ServerState") to be stored in the browser through
some state construct
- during the lifetime of the returned page in the browser,
additional state may be produced by script ("ScriptState") and
stored by some other state construct
- to qualify as state constructs in this overview, the constructs
used to store ServerState and ScriptState above should support
that the state survives the following actions:
. navigating away from, and then back again, to the current
session history entry in the browsing context, including
scenarios where the document objects have been discarded in
the meantime
. page reload/refresh of the current page (this follows from
the first point)
(there are many other actions that could be mentioned but the
above two are enough for this overview)
State that survives these criteria is "real" state in the
browser.
Server-controlled state
This is state which is created by the server application and then
transmitted to the browser where it is stored, to later be
transparently sent back to the server for identification or
processing. As it is under server control it should not rely on
script execution in the browser, so state constructs need to have
a mechanism that both automatically stores the state in browser,
and automatically transfers it back from browser to server when
appropriate. Typically the transfer back and forth between server
and browser takes place on at least every page request and
response.
Script-controlled state
This is state created and stored by script in the browser. The
preservation of state only applies to other script reading the
data and any mechanism for transfer back and forth to the server
is optional.
Scopes
State can be stored on different scopes, or contexts, to control
its reach and lifetime. HTML5 offers the following scopes where
a higher item on the list encloses lower items:
- User agent (an application containing a collection of top-level
browsing contexts)
- Browsing context (has session history with a number of
Documents)
- Document (corresponds to one page load from server but can be
associated with multiple session history entries with different
navigational states)
- Session history entry (a single navigational state for a
Document)
Apart from the different scopes, state is also kept separated by
origin, to not allow different sites to interfere with each
other's state. I will just assume origin is in effect for the
rest of this post.
User visibility
For different scenarios it may, or may not, be desired to
indicate the current state to the user through the browser user
interface. This could f ex mean being part of the URL for
bookmarkability etc. It is an advantage if the application author
can choose between state constructs both with and without user
interface exposure.
Request type (http method)
Some state constructs are unique to a certain http method. In
this overview I list GET and POST methods.
FEATURE TABLES
Below are tables comparing properties of different state
constructs. There are many alternatives to how these tables could
be organized but I've tried to keep things simple and only add
columns for the most important properties for this discussion.
SERVER-CONTROLLED STATE
Scope Visibility Request : State construct
----- ---------- ------- ---------------------
user agent, invisible, GET : cookie
user agent, invisible, POST : cookie
browsing context, invisible, GET : -
browsing context, invisible, POST : -
document, invisible, GET : -
document, invisible, POST : form hidden input *
document, url, GET : url path/query (redir)
document, url, POST : url path/query (redir)
Notes:
- the session history entry scope is not listed here as it is not
available to server code
- url-based state is only listed for Document as this isn't
applicable to user agent or browsing context
Cookies
Cookies apply to the user agent level, which typically means all
browsing contexts belonging to the same process, or in f ex
Google Chrome's case, group of processes. Actually, I haven't
found any good definition of the relation between user agent and
browsing contexts wrt the possibility of multiple user agent
instances with their own sets of browsing contexts and cookies.
The cookie spec at
http://tools.ietf.org/html/rfc2965
only mentions "user agent" in a singular form.
Form hidden input *
Hidden form data is transferred from server to browser in the
response body and is transparently sent back to the server at
postback. It is marked with (*) as it violates transparency on history
navigation with discarded state, or on page refresh, if the
initial page itself was served with POST, due to the "do you
want to resubmit?" question asked by browser user interface.
The resubmission question problem could be mitigated either by
allowing the author control over when forms need to ask for
resubmission, or by extending GET to allow for invisible state
(discussed below) so PRG can be used without losing state.
URL path/query (redirect)
URL path/query redirects can be used to transfer (small) server
state to the browser, f ex:
. http://host/randomsudoku
. application determines a suitable sudoku for this user and
redirects to:
. http://host/sudoku?no=72
Browsing context state
There currently is no support for associating state with a
browsing context. Many web application frameworks try to
workaround this "multiple windows/tabs" problem, with mixed
success. Here's a random link discussing this topic:
http://www.mail-archive.com/users@myfaces.apache.org/msg50204.html
Use-cases for browsing_context-oriented state constructs include
distinguishing between multiple conversations in different
windows/tabs, or f ex allowing the the user to be logged in on
different accounts in different windows/tabs.
A naive solution for this would be to add something similar to a
browser_context-scoped cookie.
Invisible Document state for GET requests
There currently is no support for associating invisible state
with a Document delivered with GET. This is also an area where
web frameworks have worked around this problem, and typical
workarounds are to use url-based (visible) state or to switch to
POST instead. See f ex Spring Web Flow for an example on using
the url (_flowExecutionId parameter):
http://www.javalobby.org/articles/spring-webflow/
or JSF and ASP.NET using "view states" hidden in form posts:
http://www.dotnetjohn.com/articles.aspx?articleid=71
http://books.google.com/books?id=Iv9r-CT6ZwwC&pg=PA20&source=gbs_search_r&ca
d=1_1#PPA20,M1 (see "Saving and restoring state")
(View state requirements is not an exact match to this topic but
similar enough to deserve a mention. A typical ugly pattern seen
together with this is overriding all links in a page with script,
to submit the form containing the view state to ensure it is sent
back to server.)
Use-cases include keeping state for coordinating multiple
selections over a number of steps in session history, to restore
the correct selections when going back or forward in history.
Examples of this is found in the second half of this article:
http://magazine.redhat.com/2007/10/31/continuing-the-conversation-understand
ing-seam-nested-conversations/
A naive solution for this would be to add something similar to a
Document-scoped cookie.
SCRIPT-CONTROLLED STATE
Scope Visibility : State construct
----- ---------- ---------------------
user agent, invisible : WS localStorage
browsing context, invisible : window.name, WS sessionStorage
document, invisible : -
history entry, invisible : history state
history entry, url, : url hash
Notes:
- url-based state is only listed for history entries within the
same Document as any other url change would navigate away from
the current Document with the executing script
WebStorage
WebStorage's localStorage and sessionStorage take care of the two
first scopes.
Window.name
In addition, window.name is actually also a state construct that
can share data between different Documents in the same browsing
context.
History state
HTML5's History.pushState takes care of invisible state
associated with history entries.
URL hash
Traditional hash urls http://host/page#state take care of url-
visible state asociated with history entries.
Document state
There currently is no support for associating script state on the
Document level. Any state saved in DOM or script global object
will be lost on a page reload.
Use cases would include single-page Ajax applications that want
to store data independent of a certain history entry, but at the
same time not sharing it with other page loads (Documents) of the
same application in the history of the same browsing context
(otherwise sessionStorage could be used).
Possible solutions would be to add a new "documentStorage" to
WebStorage, or to offer a History.setDocumentState method.
I welcome any discussion about the missing pieces, and possible
solutions, in these state construct listings.
Best regards
Mike Wilson
More information about the whatwg
mailing list