Understanding Ajax: Part 2
[next]
Understanding Ajax: Getting Started: Part 2
2.5 Fallback Option 1: Sending a Request Using an IFrame
IFrame
s make a suitable transport for asynchronous calls because they can load content without causing the entire page to reload, and new IFrame
elements can be created using JavaScript. The nicest attribute about an IFrame
is that a form can use one as its target, reloading that IFrame
instead of the entire page; this approach allows large amounts of data to be sent to the server using POST
.
One difficulty in using an IFrame
as a transport is that the page we’re loading needs to be HTML, and it needs to have a JavaScript onload
event handler to tell the parent document when it’s done loading. This need forces all requests being made with IFrames
to be made to pages designed to deal with IFrame
requests. (Code can’t just grab an XML file in the way that XMLHttpRequest
allows.)
Note that the use of IFrame
s does have a number of further limitations:
|
One advantage that an IFrame
has over XMLHttpRequest
is that it can be used to make file uploads. Due to browser security limitations, only user actions, such as clicking a form, can interact with files on the user’s machine. This makes targeting a form to an IFrame
the only option for file uploads that do not involve a normal form POST
and page reload cycle. However, there is no reason you can’t fall back to using an IFrame
for file uploads and XMLHttpRequest
for the rest of your Ajax requests. Unless you are making remote scripting-style Ajax requests (which is covered in Chapter 3, "Consuming the Sent Data"), working around IFrame
limitations will add a significant amount of work to any Ajax development project.
2.5.1 Creating a Hidden IFrame
To get maximum compatibility with older browsers, you could just add the IFrame
to your HTML and give it a size of 0x0. (You can’t just hide it, or some browsers won’t load it.) However, this approach isn’t flexible, so you will want to create the frame dynamically. Not all older browsers support document.createElement,
but browsers without that support will generally lack the other dynamic capabilities needed to use the data you’re loading, so it’s best to provide support to them with a static HTML version of the page. In the following example, the IFrame
is created using innerHTML
because it’s simpler than creating it using DOM methods. Note, however, that it could also be created with document.createElement
, just like the div
to which it’s being added:
2.5.2 Creating a Form
If you want to make only a GET
request, you can change the value of the IFrame
’s src
property, but to do POST
, you need to use a targeted form. GET
isn’t a good solution for Ajax requests for two reasons: it can send only a limited amount of data (an amount that changes depending on the browser), and GET
can be cached and/or preloaded by proxy servers, so you never want to use it to perform an action such as updating your database.
Using a form with an IFrame
is easy. Just set the form’s target
attribute, and when you submit the form, the result loads in the IFrame
. The following example creates our form and sets its targets to the IFrame
we created earlier in the "Creating a Hidden IFrame
" section of the chapter:
2.5.3 Send Data from the Loaded Content to the Original Document
The only way to know that the content of the IFrame
has loaded is to have the content page run some JavaScript that notifies the parent page in which the IFrame
is embedded. The simplest way to do this is to set the onload
event handler on the document you are loading. This limitation means you can’t use an IFrame
for loading arbitrary content like you can with XMLHttpRequest
. However, it’s still useful for cases in which a single server page is already being used as an Ajax gateway. Here is an example of onload
:
2.5.4 Complete IFrame
Ajax Example
A full example of an IFrame
that Ajax requests includes two pieces. The first piece is the client-side code to create the IFrame
and form. The second piece is the server-side code, which prepares some data and sends it back to the parent document in its onload
event handler.
The first part of the example (Listing 2-5) is the JavaScript code in a simple HTML file. This page is used for testing; the callback function just alerts the contents of the results. The second part of the example (Listing 2-6) is a simple PHP script, which takes the data from POST
and sends it back to the parent document. To make a useful system, you might also want to include some extra variables in the form, which would tell the PHP code what to do with the uploaded data, or you could put the logic directly into the script and use a different target page for each task you wanted to accomplish.
Listing 2-5 Making an Ajax Request Using an IFrame
Listing 2-5 is made up of three functions:
-
createRemotingDiv
for setting up theIFrame
. -
sendRequest
for making an Ajax request. -
test
for making an Ajax request. Thetest
function is tied to a link (line 55) in the pages’ HTML. Clicking on this link allows the user to start an Ajax request.
The createRemotingDiv
function (lines 5–28) combines the previously described code for creating a hidden IFrame
with the code for creating a form to submit to it. When the form is created, it’s targeted against the newly created IFrame
, making the form submission use it instead of reloading the current page. Showing the IFrame
during development is often useful in the debugging process so that you can see any output generated by the page you’re calling. You can do this by editing the style on line 8 and changing it to width:200;height:200;
.
The sendRequest
function (lines 30–40) makes an Ajax request. It takes the URL to which to make the request, a payload to send to the server, and a callback function to run when the request is complete. The function uses createRemotingDiv
to set up the process (lines 31–34). Then sendRequest
updates the action on the IFrame
form (line 35), adds the payload value on the form, and submits the form using the IFrame
. When the new page is loaded into the IFrame
, the new document uses a JavaScript onload
handler to call the callback function that was passed into the sendRequest
method. The PHP page that processes the form POST
and creates the onload
JavaScript is shown in Listing 2-6.
Listing 2-6 PHP Server Page That Handles an IFrame
Ajax Request
On the server side, the form is processed and output is created in the form of an HTML page. The simplest way to add new data is to generate JavaScript containing the new data. In this case, we are just echoing the data back to the client by putting it in the result variable (lines 4–6). Normally, you’ll be running server-side code here and either outputting a string (as in this case) or adding new JavaScript code to run against the parent document. The callback
function on the parent is called by the onload
handler on the body tag (line 11).
[next]
URL: