No standard, reliable way to get FORM data to
an Ajax request.
A web site has a form containing multiple form fields.
This data needs to be sent to the server to be verified.
However, the author does not want to affect history state.
After submitting the form, a message appears on the page displaying customized
details from the server.
From the user's perspective, he is still on the same page.
The need for Form Serialization has manifested itself strongly in all of today's popular Ajax libraries, however:
The need for File serialization is formally recognized, is being standardized
in the File and FileList specifications
[File Upload], and is implemented in
Mozilla Firefox [bug 371432]. File serialization now makes it possible to
send a file using XMLHttpRequest, although the
functionality has not gotten mainstream acceptance (too early).
Most JavaScript libraries will create and then target a hidden IFRAME
when a FORM to be serialized for an Ajax request
contains a file input. This has some drawbacks, as we will see.
Lets examine some other possibilities.
XMLHttpRequest
IFRAME
XMLHttpRequest method
setForm( ) (contrasting new idea)
IFRAME (idea to solve problems with hidden IFRAME
loader/proxy)
Add to HTMLFormElement interface, the
following methods:
toJSONString getDataSetString
Both methods will return a serialized representation of the FORM's successful
controls.
Many Ajax apps use forms to provide a UI to model data. There are some benefits to this approach:
XMLHttpRequest
XMLHttpRequest supports
responseXML in an abstract view, as model data
on the client
XMLHttpRequest is reported to be
faster than an IFRAME
[xml-http-performance-and-caching]
input type="image"
off a FORM submit, as required by the HTML FORM specification.
FORM must be serialized by
hand. Most Ajax apps already use a library; however Ajax libraries offer some
considerable problems:
FORM submit in that
form submit event handler. Libraries that support this requirement do so with much
bloat and complexity. The hoop-jumping, logic is often inextricable; forcing the user to
depend on the library (complex, future-legacy code which ranges from 50-100k).*
jQuery does this; YUI conflates the Form Serialization logic with the "Connection Manager" (XHR wrapper) (not cohesive, violates SRP ). In order to conform to the HTML FORM specification, the libraries MUST do this. Getting the seldom used coordinates off an image submit is a non-trivial requirement, and library authors bear this burden.
FORM Serialization by hand is not completely possible.
What is possible to do is complicated and authors often make honest mistakes in attempts to
serialize the HTML FORM's successful controls.
IFRAME. This makes no sense for
model XML or JSON and will cause HTML tags to be inserted into the document.
If the content is HTML, scripts will be downloaded and run.
Other external resources will also be downloaded to the IFRAME's
contentDocument.
IFRAME is not
directly intended to be hidden and used for the targeting of requests, but is
instead intended to “allow authors to present documents in multiple
views” [FRAMES]
IFRAME (inconsistencies such as the 'click and
throb' in IE)
Conclusion: Using an IFRAME to
accommodate this use case will work, but has certain implications that make it
less desirable.
FORM
BUTTON wrong (uses
innerHTML instead of value, sends BUTTON when
not clicked).
Conclusion: Does not correctly satisfy use case.
FORM Serialization (new proposal):
toJSONString getDataSetString
Files will be serialized according to the [File Upload] specification. This is implemented in Mozilla Firefox [bug 371432].
The HTMLFormElement interface
interface HTMLFormElement {
string getDataSetString(); raises FileException
string toJSONString(); raises FileException
};
toJSONString returns a JSON string with keys as names of successful controls and values
as an array containing values of their associated key.
For successful conrols that have the same name (such as OPTION or checkbox),
the value is an array, so to keep the API consistent, we use an array for every value, even when the
array contains only one item.
getDataSetString returns a URI string defined by
HTML FORM specification.
FORM
specification:
XMLHttpRequest that are
well-defined by the w3c and supported in modern browsers
HTMLFormElement interface
getDataSetString
toJSONString
JSON objects.
toJSONString is already going to
be part of Object.prototype in ES4. This is
planned to be supported in Firefox 3 and IE8, via a plugin distributed with
the browser, but may be included in Mozilla sooner [Bug 340987].
GET)
FORM's data
is specified in many formats, but not in JSON format.
This proposal begs a change to form data: seeding, as JSON would not be round-trip, but only a one way API (we
(need a way to set form data with a JSON object using the
data: scheme in Web Forms 2.0).
Note: There is reasonable speculation in the
JSONRequest whitepaper that
JSON will be used to transfer data between
sites and will be more widely used in the future JSONRequest
Conclusion: Can be used to satisfy use case.
Would a toJSON() method be more useful than toJSONString()?
The resulting object of a toJSON method could still be very easily converted to a String via native code. Would
toJSON represent a significant need to fulfill a variant use-case (offline, browser-side cache)?
Would this make it easier for persistance using JSPON.
XMLHttpRequest
method setForm( form
) (contrasting new proposal)
XMLHttpRequest's public interface
PUT or
DELETE, only
GET and POST.
(although this could also be changed)
XMLHttpRequest to HTMLFormElement.
IFRAME to make it act like an XMLHttpRequest
Add the ability to get Progress events 1.0, cancel loads, and prevent rendering on the window object.
Modify the HTML specification to state that
IFRAME can also be used as a transport
mechanism.
HTMLIframeElement {
attribute useHistory boolean
attribute render boolean
attribute response, object
useHistory
boolean, default value is true
IFRAME loads.
render, boolean, default value is
trueIFRAME does not render its
contentDocument
response, object,
IFRAME is already in use
responseXML in an abstract view,
as model data on the client.
IFRAME element which requires changes to the
existing IFRAME element.
IFRAME is not intended to be hidden and used
for the targeting of requests, but is instead intended to 'allow authors to
present documents in multiple views'
[FRAMES].
useHistory render response
POST. (could also be changed)
contentDocument (an alternative to
responseXML) is rendered by the
IFRAME, which is not desirable in the use
case.
IFRAME load
IFRAME not change history
Conclusion: Can be used to satisfy use case.
This is not really an option, as current web applications make heavy use of this with existing technological methodologies mentioned earlier.
FORM has widespread acknowledgementFORM serialization as per original HTML 4 spec (1997),
yet no official reccommendation requires that they expose this behavior to the scripting environment,
and in fact, none do.FORM