This API is an improvement over the original qx.io.remote.*
API , but does not offer the same feature-set
yet. It is recommended to use the classes in this API for your
development. The REST abstraction API is based on this API.
Qooxdoo ships with two transport methods, interfaced by qx.io.request.Xhr
and
qx.io.request.Jsonp
.
-
Choose
Xhr
whenever you can.Xhr
offers true HTTP client functionality and exposes metadata associated with HTTP requests. It is agnostic of the data interchange format and does not make any specific demands on the backend. -
If you are making cross-origin requests and need to support all popular browsers and/or the target server is not configured to accept cross-origin request (
Access-Control-Allow-Origin
header), you will need to useJsonp
. Only JSON is supported as data interchange format and the server needs to wrap responses in a JavaScript function call.
Xhr
and Jsonp
share a common interface. AbstractRequest
defines the lowest
common denominator of both transport methods.
Before a request can be send, it must be configured. Configuration is accomplished by setting properties. The most commonly used properties include:
- url: The HTTP resource to request
- method: The HTTP method, sometimes also referred to as HTTP verb.
Script
only accepts theGET
method. - requestData: Data to be send as part of the request.
- requestHeaders: Headers to send with the request
For a complete list of properties, please refer to the API Documentation of qx.io.request:
// Instantiate request
var req = new qx.io.request.Xhr();
// Set URL (mandatory)
req.setUrl("/books");
// Set method (defaults to GET)
req.setMethod("POST");
// Alternative notation
// var req = new qx.io.request.Xhr("/books", "POST");
// Set request data. Accepts String, Map
// or Qooxdoo Object.
req.setRequestData({ title: "The title" });
// Send request
req.send();
Once a request is sent using the send()
method, it traverses various states.
There are two ways to query the current state of the request.
-
getReadyState(): An integer (0-4) representing UNSENT, OPENED, HEADERS_RECEIVED, LOADING and DONE.
-
getPhase(): Symbolic state mapping to deterministic events (success, abort, timeout, statusError) and intermediate readyStates.
Events are fired when the request is progressing from one state to the other. The most important events in the lifecycle of a request include:
-
load: Request completed successfully.
-
success: Request completed successfully (like
load
) and the response can be expected to contain the kind of data requested. ForXhr
this means the HTTP status of the response indicates success (e.g.200
). ForJsonp
, the script received executed the expected callback. -
statusError: Request completed successfully (like
load
) but the additional requirements forsuccess
are not met. ForXhr
this event is typically fired when the server reports that an erroneous or unknown resource was requested (e.g.500
or404
). ForJsonp
, this event is associated with an invalid response for whatever reasons. -
fail: Any kind of error occurred. Catches distinct events
error
,statusError
andtimeout
.
For a complete list of events, please refer to the API Documentation of qx.io.request:
req.addListener(
"success",
function (e) {
var req = e.getTarget();
var response = req.getResponse();
this.doSomething(response);
},
this
);
// Send request
req.send();
Once the request completed, a range of getters return details about the response.
-
getResponse(): Response processed according to parser settings or content type (
Xhr
). Always JSON for (Jsonp
). -
getStatus(): The numerical status of the response. For
Xhr
the status is the HTTP status.Jsonp
only knows200
(when callback was executed) and500
(when it was not).
There are two ways to handle authentication. The lower-level approach is to
manually set the adequate request headers. The high-level, recommended way is to
assign the authentication
property an instance of a class that implements the
IAuthentication
interface. This class defines the necessary request headers
and can handle the authentication logic. Basic
implements the most basic kind
of authentication (HTTP Basic) and serves as an example for more advanced
authentication methods.
The request's response can be bound to a widget, model or any other object using
data binding. This feature is provided by the changeResponse
event, fired on
change of the (parsed) response.
// Bind response to value of a label
//
// req is an instance of qx.io.request.*,
// label an instance of qx.ui.basic.Label
req.bind("response", label, "value");
If you encounter odd behavior, it might help to enable debugging of the IO
classes. Debugging is controlled with the qx.debug.io
setting. Provided you
have allowed URL settings (allowUrlSetting
), you can simply append
?qxenv:qx.debug.io:true
to the URL of your application.
Features specific to Xhr
.
By default, response
is populated with the response parsed according to the
response content type. For the built-in parsers, parsing always results in a
JavaScript object.
The content type is read from Content-Type
response header. If the response
content type is unrecognized, no parsing is done and response
equals
responseText
. Parsers associated to a content type are:
- JSON: application/json
- XML: application/xml
The parser can be explicitly set with setParser()
. This can be useful if the
content type returned from the server is wrong or the response needs special
parsing. The setter accepts either a symbolic string ("json"
or "xml"
) or a
function. If a function is given, this function is called once the request
completes. It receives the raw response as first argument. The return value
determines the response
.
- getResponseText(): Raw, unprocessed response
- getResponseHeader(header)
- getAllResponseHeaders()
Some servers send distinct representations of the same resource depending on
the content type accepted. For instance, a server may respond with either a
JSON, XML or a HTML representation while requesting the same URL. By default,
requests accept every content type. In effect, the server will respond with it's
default representation. If the server has no default representation, it may
respond with the status code 406
(Not Acceptable).
In order to choose a representation, set the accepted response content type with
setAccept()
. It is a good practice to always set the preferred representation
to guard against possible changes of the server's default behavior.
For more details, see Accept header in the HTTP 1.1 specification.
Usually, one or more caches sit between the browser sending the request and the server answering the request. The most important cache is arguably the browser cache, which is enabled by default in all modern browsers. Other caches include various kinds of proxy servers. Understanding caches is vital to reduce latency and save bandwidth. However, a detailed introduction of HTTP caching is beyond the scope of this section. For more information, refer to the Caching tutorial .
To control the behavior of caches on the client-side, a number of HTTP
Cache-Control directives can be sent as part of the request by setting the
cache
property. To circumvent caching, a common trick is to add a random
string to the URL's query part. This is accomplished by setting cache
to
false
.
Features specific to Jsonp
.
Callback handling is done behind the scenes but can be customized. If the
service only accepts a special callback parameter to read the desired callback
function name from, this parameter can be set with setCallbackParam()
. Some
services do not allow custom callback names at all. In this case,
setCallbackName()
wires the request to the fixed callback name.
No Cache-Control directives can be set, but caching can be disabled by setting
cache
to false
. Works by adding a random string to the URL's query part.