termlib.js home | multiple terminals | parser | faq | documentation | samples
Server Request Sample
 
> open terminal 

Tests:

> 1) a simple request 

> 2) a JSON request  

 
 
(c) mass:werk,
N. Landsteiner 2005-2007
http://www.masswerk.at

termlib-Socket Sample
 

This page demos the termlib.js socket extension for client-server communication via asynchronous XMLHttpRequests (commonly known as AJAX).

The socket extension provides a tight integration for all XMLHttpRequest tasks that would commonly occur in a real world application.

All you have to do, is call the send( <options> ) method and return.
The request (might it succeed or fail) will come back to your callback-handler with your Terminal instance set as the this object.

example:

  // assume we are inside a handler
  // ("this" refers to an instance of Terminal)
  
  this.send(
    {
      url:      "my_service.cgi",
      method:   "post",
      data:     myDataObject,
      callback: mySocketCallback
    }
  );
  return;
  
  function mySocketCallback() {
    if (this.socket.succes) {
       // status 200 OK
       this.write("Server said:\n" + this.socket.responseText);
    }
    else if (this.socket.errno) {
       // connection failed
       this.write("Connection error: " + this.socket.errstring);
    }
    else {
       // connection succeeded, but server returned other status than 2xx
       this.write("Server returned: " +
                  this.socket.status + " " + this.socket.statusText);
    }
    this.prompt()
  }

 
The send() API:

As send( <options> ) is called the socket library creates a XMLHttpRequest, collects and escapes the provided data, executes any initial tasks, and sends the request.

All settings are transfered via a single options-object containing one ore more of the following options:

url the request url, must be on the same host (default "")
method request method (GET or POST; default GET)
data request data (default ""), may be of any type, preferably an object with key-value pairs.
the data is serialized and escaped for you by the library. (Please note that there might be unexpected results with nested objects or arrays. By the way: arrays are serialized as comma separated lists.) For complex data structures use a XML-object (true AJAX, see below).
The resulting string will be either appended to the request url (GET) or used as post-body.
callback the callback-function to handled the response
 
advanced settings:
postbody Use this for true AJAX (e.g. sending a XML-object to the server)
If a postbody option is supplied, this will change the behavior as follows:
1) the request method is forced to "POST"
2) the postbody will be used instead of any supplied data object
3) the postbody will be transmitted as is (no serializing or escaping)
(Note: The creation and parsing of XML-objects is out of the scope of this document and termlib.js and is therefor left entirely up to you.)
userid optional user-id for implicit login (transfered without encryption!)
password optional password for implicit login (transfered without encryption!)
mimetype optional MIME-type to override the response's default MIME
headers optional object (key-value pairs) of HTTP-headers to be included in the request
getHeaders optional array (or object with labels as keys) of HTTP-headers to be extracted from the response
timeout optional individual timeout in msecs for this request
(default: 10000)

send() will add a parameter "_termlib_reqid" with a unique id to every GET request that doesn't target the local file system (sent from pages with the "file:" schemes). This additional parameter ensures that MSIE (MS Internet Explorer) will truly fetch the requested document instead of serving it from its cache.

A word on local requests:
Please note that local requests (from and to the local file system) won't work with MSIE 7. (Sorry, ask Bill.) This MSIE 7 error will be captured as connection error with errno 2 ("Could not open XMLHttpRequest.").
If a browser requests a local document that does not exist, a 404 (Not Found) status code will be generated by the library and the errno property will be set to 5 ("The requested local document was not found.").

 
Global Config Settings:

There are a few global settings in Terminal.prototype._HttpSocket.prototype (the prototype of the internal socket object used by the library), which define some default values:

useXMLEncoding Boolean flag (default: false) for parameter delimiters
if false, parameters will be delimited by "&".
if true, parameters will be delimited using ";" (new XML compatible syntax).
defaulTimeout Number of ticks (milliseconds, default: 10000 = 10 sec) for request timeout, if not specified else.
defaultMethod String (default: "GET"); request method to use, if not specified else.
forceNewline Boolean flag (default: true): translate line breaks in the responseText to newlines (\n).

 
The Callback (Response Handling):

Any request issued by send() will trigger the handler specified by the callback option (or a basic default-handler). The callback will be called in any case, should the request succeed, timeout or fail otherwise.

All response data (and some of the request data) is provided in a temporary "socket object for your convenience. (This temporary object will be discarded just after the callback returns.) As the this object points to your instance of Terminal, this object will be available as "this.socket" inside your callback-handler.

Properties of the socket object:

status the HTTP status code (e.g.: 200, 404) or 0 (zero) on timeout and network errors
statusText the HTTP status text (e.g.: "OK", "Not Found")
responseText the transmitted text (response body)
line breaks will be normalized to newlines (\n) if _HttpSocket.prototype.forceNewline == true (default behavior)
responseXML the response body as XML object (if applicable)
success a simple boolean flag for a 2xx OK response
headers object containing any HTTP headers (as key-value pairs) of the response, which where requested by the "getHeaders"-option of the send().
the header-labels are unified to "camelCase"
e.g.: "Content-Length" will be in headers.contentLength
 
stored request data:
url the request url as specified in the send() options.
data the data you called send() with
query the composed query-string or postbody as transmitted to the host
method the request method
errno the internal error number (0: no error)
errstring the internal error message ("": no error)

Some of the response specific data (as status codes, or headers) might not be present with local connections.

 
Connection errors are classified with the following errno and errstring values:

errno errstring label
0 "" OK
1 "XMLHttpRequest not implemented." NOTIMPLEMENTED
2 "Could not open XMLHttpRequest." FATALERROR
3 "The connection timed out." TIMEOUT
4 "Network error." NETWORKERROR
5 "The requested local document was not found." LOCALFILEERROR

The labels are implemented as key-value pairs in Terminal.prototype._HttpSocket.prototype.errno (type "object").
Error codes (errno) are also accessible as this.socket.ErrorCodes at run-time.

example:

  // assume we are inside a handler
  if (this.socket.errno == this.socket.ErrorCodes.TIMEOUT) {
     this.write("Oops, the request encountered a timeout.");
  }

Inside an interactive terminal session you'll usually want to return just after send() and call prompt() at the end of your callback-handler.
This way the terminal will keep blocked until the callback is finished.

Aside from this, the socket extension provides also the means for background tasks (e.g. storing temporary status on a server etc.) that do not need visual feedback or user interaction. Since the requests are performed and handled asynchronous and object oriented, both will go side by side.

 

Norbert Landsteiner
Vienna, 2007/03
Updated 2010/01