Next, create a new YUI instance for your application and populate it with the
modules you need by specifying them as arguments to the YUI().use() method.
YUI will automatically load any dependencies required by the modules you
specify.

A Simple Transaction

The io() method on the YUI instance is the static method for making an HTTP request. This method accepts two arguments: the uri and the configuration object.

uri: This parameter specifies the URI for the transaction

configuration: This parameter is an object of keys and values of configurations specific to the transaction. Please see: The Configuration Object for more information on all available configuration properties.

NOTE: You will need compile and host your own io.swf file to enable this module.
Necessary source files are available in the yui3-swfs repository.

io-form

This module extends io-base, to add the ability to serialize HTML form data for POST transactions.

io-upload-iframe

This module extends io-base, to allow file uploads with an HTML form, using an iframe as the transaction transport.

io-queue

This module extends io-base, to provide a basic queue interface for io.

io-nodejs

Conditional module that provides a transport for Node.js.

The Configuration Object

This object is the second argument of io(). Its properties define transaction parameters and transaction response handling. The configuration object and all configuration properties are optional. The following table describes all configuration properties used by IO.

Property

Description

method (string)

Defines the HTTP method for the transaction. If this property is undefined or omitted, the default value is GET.

data (string)

Data to be sent with the transaction, defined as a string of key-value pairs(e.g., "foo=bar&baz=boo".) Data can also be defined as a single-level object(e.g., { 'foo':'bar', 'baz':'boo' }), which is then serialized into a key-value string. To use this capability, the sub-module querystring-stringify-simple, an optional dependency for io-base, must be declared in Y.use().

headers (object)

Specific HTTP headers and values to be sent with the transaction (e.g., { 'Content-Type': 'application/xml; charset=utf-8' } ).

username (string).

Username for a basic HTTP authentication (e.g. .htaccess).

password (string).

Password for a basic HTTP authentication (e.g. .htaccess).

on (object)

This object can be used to register transaction event handlers for the set of supported io events, listed below. These events fire in addition to the global io events. All events handlers are optional.

start:event handler

complete:event handler

success:event handler

failure:event handler

end:event handler

NOTE: These events are accessible only to the transaction's subscribers, whereas global IO events are accessible by all subscribers.

context (object)

Defines the execution context of the event handler functions for the transaction. If undefined, a default value of Y(the YUI instance) is used.

form (object)

This object instructs io to use the labels and values of the specified HTML form as data.

id: This property can be defined as the id(String) of an HTML form or an object reference of the HTML form.

useDisabled: When set to true, disabled field values are included as part of the data. The default value is false.

xdr (object)

Defines the transport to be used for cross-domain requests (e.g., { use:'flash' } ). The transaction will use the specified transport instead of the default transport, when specified in the transaction's configuration object.

use: This property specifies the type of transport to be used; the io-xdr (deprecated) module provides 'native' and 'flash' transports.

dataType: When set to 'xml', io will return the response data as an XML document, if necessary.

NOTE: You will need compile and host your own io.swf file to enable this module. Necessary source files are available in the yui3-swfs repository.

sync (boolean)

When set to true, the transaction will be processed synchronous, and will halt all code execution until the transaction is complete.

arguments (object)

Object, array, string, or number passed to all registered, transaction event handlers. This value is available as the second argument in the "start" and "end" event handlers; and, it is the third argument in the "complete", "success", and "failure" event handlers.

timeout

This value, defined as milliseconds, is a time threshold for the transaction (e.g., { timeout: 2000 } ). When this limit is reached, and the transaction's Complete event has not yet fired, the transaction will be aborted.

This is an example of a configuration object, with a set of properties defined.

/*
* This is an example configuration object with all properties defined.
*
* method: This transaction will use HTTP POST.
* data: "user=yahoo" is the POST data.
* headers: Object of HTTP request headers for this transaction. The
* first header defines "Content-Type" and the second is a
* custom header.
* on: Object of defined event handlers for "start", "complete",
* and "end". These handlers are methods of an object
* named "Dispatch".
* context: Event handlers will execute in the proper object context,
* so usage 'this' will reference Dispatch.
* form: Object specifying the HTML form to be serialized into a key-value
* string and sent as data; and, informing io to include disabled
* HTML form fields as part of the data. If input type of "file"
* is present, setting the upload property to "true" will create an
* alternate transport, to submit the HTML form with the
* selected files.
* xdr: Instructs io to use the defined transport, in this case Flash,
* to make a cross-domain request for this transaction.
* arguments: Object of data, passed as an argument to the event
* handlers.
*/
var cfg = {
method: 'POST',
data: 'user=yahoo',
headers: {
'Content-Type': 'application/json',
},
on: {
start: Dispatch.start,
complete: Dispatch.complete,
end: Dispatch.end
},
context: Dispatch,
form: {
id: formObject,
useDisabled: true,
upload: true
},
xdr: {
use: 'flash',
dataType: 'xml'
},
arguments: {
start: 'foo',
complete: 'bar',
end: 'baz'
}
};

The Response Object

When a transaction, using the XHR object as a transport, is complete, the response data are passed as an object to the event handler.

Field

Description

status

The HTTP status code of the transaction.

statusText

The HTTP status message.

getResponseHeader(headername)

Returns the string value of the specified header label.

getAllResponseHeaders()

All response HTTP headers are available as a string. Each key-value pair is delimited by "\n".

responseText

The response data as a decoded string.

responseXML

The response data as an XML document.

NOTE: Transactions involving file upload or cross-domain requests, using alternate transports, will only populate the responseText or responseXML field. The HTTP status and response headers are either inaccessible or unavailable to these alternate transports.

Events

IO events provide access to state and data during a transaction's lifecycle. There are two aspects to io events: global and transaction. Global events are always fired by io for all transactions, and these events are accessible to all event subscribers. Transaction events are created and fired if they have handlers defined in the configuration object. Global events are identified by the io:eventname pattern.

The following table describes the available io events and provides examples of how to subscribe to them globally:

Event

Description

io:start

Fires when a request is made to a resource. The event handler's arguments signature is:

Fires after the "complete" event, when the response HTTP status resolves to 4xx. 5xx, undefined, or a non-standard HTTP status. This event also includes 'abort' and 'timeout' conditions. The event handler's arguments signature is:

Synchronous Transactions

For same-domain requests, YUI io can be instructed to send a synchronous request, which will halt all script execution until the transaction is complete. When the transaction is complete, the response data are directly accessible through the object returned by Y.io(), and the data are also accessible through all io events. When making synchronous requests, abort() and isInProgress() are not available.

Cross-Domain Transactions

By default, io uses the XMLHttpRequest object as the transport for HTTP transactions. It can also be configured to use an alternate transport to make cross-domain, HTTP transactions. Currently, io can make use of Flash as an alternate transport. To prepare io for Flash-based, cross-domain transactions, the transport io.swf must be deployed and accessible to YUI io. (The file "io.swf" can be found in YUI io's build directory in the YUI3 download at: http://yuilibrary.com/downloads/.) For each transaction, the configuration object's xdr object must be defined as { use: 'flash' } so io will use the designated transport instead of using the default XMLHttpRequest transport.

As io.swf is written in ActionScript 3, Flash Player 9 or better is required (version 9.0.124 or better is recommended). Additionally, a cross-domain policy file must be deployed at the resource to grant the client access to the remote domain. A cross-domain request will not be successful without this policy file hosted at the resource. The following example file grants permissive access to the host from all requests, but the host will only accept custom HTTP headers originating from yahoo.com.

NOTE: You will need compile and host your own io.swf file to enable this module. Necessary source files are available in the yui3-swfs repository.

NOTE: Cross-domain transactions do not fire the global io:complete event and the transaction-specific complete event, when using the IE XDomainRequest or the Flash transport. All other events in the transaction lifecycle are fired.

A subset of A-grade browsers are capable of making cross-domain requests, using XMLHttpRequest, requiring specific access control headers be served from the resource. To use this feature, the xdr configuration must be defined with: { use: 'native' }. IO will try to resolve the request using the native transport, and it will fall back to the Flash transport if the initial attempt throws an exception due to the browser lacking native support.

NOTE: For native cross-domain requests to work, the resource must respond with the "Access-Control-Allow-Origin" header with a value permitting the client to make the request. In the absence of this HTTP response header, the transaction will always fail. Please see the following articles for more information on this topic.

Serializing HTML Form as Data

IO can serialize HTML form fields into a string of UTF-8 encoded, name-value pairs. If the transaction is HTTP GET, the data are appended to the URI as a querystring. If the transaction if HTTP POST, the data will be the POST message.

Uploading Files in an HTML Form

The default XHR transport, used in IO, cannot upload HTML form data that include elements of type="file". In this situation, IO will use an alternate transport -- an iframe -- to facilitate the transaction. The response data must be one of the following content types: "text/html", "text/plain", "text/xml". The following example shows how to configure a transaction involving file upload:

When performing a file upload, a subset of global and transaction events will be fired. Specifically, these are:

Start

Complete

End

Success and Failure events are not processed and fired because the iframe transport does not provide access to the HTTP status and response headers, to reliably determine those conditions.

Setting HTTP Headers

IO can be configure to send default, user-defined HTTP Headers for all transactions, in addition to any headers defined in the configuration object. Headers can be set or removed as needed. The following example shows how to set and how to delete default headers in IO:

YUI().use("io-base", function(Y) {
// Set a new default HTTP header.
Y.io.header('Content-Type', 'application/json');
// To remove an existing header, use the same method, but omit the value.
Y.io.header('Content-Type');
});

Custom HTTP headers may or may not be sent in cross-domain requests. This is may be due to limitations of the transport, or specific "Access-Control" headers requirement.

Queue

IO's queue module provides FIFO transaction response while keeping each transaction asynchronous and non-blocking. Specifically, transactions are handled -- by global or transaction event handlers -- in the order they are sent, regardless of actual server response order. Transactions can be promoted to the front of the queue, or they can be purged from the queue, as well.

Field

Description

queue(uri, configuration)

Method signature is identical to io, but returns the id of the transaction.

queue.start()

Activates the queue, and begins processing transactions in the queue. This is the default state of the queue.

queue.stop()

Deactivates the queue. Transactions sent to queue() will be stored until the queue is re-started.

queue.promote(id)

Moves the specified transaction stored in the queue to the head of the queue.

queue.remove(id)

Deletes the specified transaction stored in the queue.

// Create a YUI instance using the io queue sub-module.
YUI().use("io-queue", function(Y) {
// Stop the queue so transactions can be stored.
Y.io.queue.stop();
// Send four transactions into the queue. Each response will arrive
// in synchronous order.
var task0 = Y.io.queue(uri);
var task1 = Y.io.queue(uri);
var task2 = Y.io.queue(uri);
var task3 = Y.io.queue(uri);
// Promote task2 to the top of the queue.
Y.io.queue.promote(task2);
// Remove task3 from the queue.
Y.io.queue.remove(task3);
// Re-start the queue.
// Transactions are sent in the following order: task2, task0, task 1.
// Transaction callbacks, if provided, will be processed in the same
// sequence: task2, task0, task1, regardless of actual response order.
Y.io.queue.start();
});

Instantiating IO

As of 3.4.0, IO is instantiatiable. An IO instance avails its public and private fields, allowing for customizations as needed.

// Create a new instance of IO.
var io = new Y.IO();
// Send a request using the new Y.IO instance.
// This is analogous to the static method
// Y.io()
io.send(uri, configuration);

In addition to being instantiable, IO is now an EventTarget, and IO's global events can be configured at instantiation time.

// This simple example creates a new instance of IO and passes
// Custom Event configurations that instructs IO to emit
// Event Facades for all its events, and allow the events to
// bubble to other registered event targets, if any.
var io = new Y.IO({
emitFacade: true, // Event handlers will receive an Event Facade.
bubbles: true, // Events will bubble to registered event targets.
});

If IO is configured to emit Event Facades, each event handler will receive the Event Facade as the argument.

// This is the event handler using Event Facades.
var configuration = {
on: {
complete: function(o) {
/*
* o is the event facade, and contains the following fields:
* - o.id is the transaction id.
* - o.data is the XMLHttpRequest (or other transport) object.
* - o.arguments is the user-defined arguments, if any.
* - o.cfg is the configuration object used for this transaction.
*
* These fields are in addition to the Event Facade's fields.
*/
}
}
};
// For comparison, this is the regular event handler, when
// not emitting Event Facades as described in the previous
// sections on "The Response Object" and "Events."
var configuration = {
on: {
complete: function(id, xhr, arguments) {
// id is the transaction id.
// xhr is the XMLHttpRequest object.
// arguments is the user-defined arguments, if any.
}
}
};

Using IO in Node.js

The io-base module works out of the box and mimic's it's browser counterpart as much as it can.

NOTE: You can not use the io module on the server, the io module
contains the io-form and the io-upload-frame modules which both rely on a working DOM
to be available. The io-base module, however, has no requirement on a DOM.

Security Bulletin

A security vulnerability exists in the XDR transport io.swf when using the io-xdr sub-module to make cross-domain requests. This vulnerability allows third-party sites to load io.swf from a remote domain and issue HTTP requests with the SWF's domain credentials. Please examine the following use cases, and, if applicable to you, please follow the recommended actions to close this exploit.

You currently host io.swf from YUI 3.1.0, 3.1.1, or 3.2.0pr1, and your application uses the io-xdr sub-module to make cross-domain requests. Solution: replace the version of io.swf with io.swf from YUI 3.1.2.

Your application uses the io-xdr sub-module from version YUI 3.1.0, 3.1.1, and you explicitly load io.swf from http://yui.yahooapis.com/version/build/io.swf (where version matches the affected YUI versions). Solution: modify your application's crossdomain.xml so that allow-access-from domain= does not allow access from yui.yahooapis.com. Download YUI 3.1.2 and deploy io.swf on your application's domain instead of loading it from yui.yahooapis.com.

Your application uses the io-xdr sub-module from version YUI 3.1.0, 3.1.1, and you explicitly load io.swf from a disparate domain, and you have a crossdomain policy file allowing access from the SWF's domain. Solution: modify your application's crossdomain.xml so that allow-access-from domain= does not allow access from the domain serving io.swf. Download YUI 3.1.2 and deploy io.swf on your application's domain instead of loading it from a remote domain.

If you use io.swf from YUI 3.0.0 you are not affected by this vulnerability.

Beginning with YUI 3.1.2, io.swf will no longer be accessible from yui.yahooapis.com. You will be required to host and serve io.swf, if you wish to employ it as an XDR transport.

Beginning with YUI 3.13.0, io.swf will no longer ship with YUI. You will need compile and host your own io.swf file to enable the xdr module. Necessary source files are available in the yui3-swfs repository.

Known Issues

Multiple HTML Submit buttons, in an HTML form, are not supported at this time.