XMLHTTPrequest usually uses asynchronous reply through a callback which I think cannot be directly implemented in jsdb. However, the synchronous mode can be implemented.
Below see an implementation of XMLHTTPRequest and a test program.
http://en.wikipedia.org/wiki/XMLHttpRequestI only implemented the basic functionality (that is, no https, no proxy support, only GET , POST methods, no deflate but should be easy to add)
As mentioned in this thread do not expect the entire DOM (this is not a browser)
/* XMLHTTPRequest.js
* Copyright (C) 2014 gilado
*/
XMLHttpRequest = function()
{
var method = null;
var url = null;
var async = true;
var auth = null;
var path = null;
var host = null;
var port = null;
var hdrs = [];
var stm = null;
var this_ = null;
var response = {}; // Set below
this.readyState = 0;
this.responseText = null;
this.open = function(method_,url_,async_,user_,pass_)
{
method = null;
async = true;
auth = null;
hdrs = [];
if (stm) stm.close();
stm = null;
this_ = null;
var a = url_.match(/^(.*):\/\/([^\/]*)[\/]?(.*)$/);
if (!a || a.length < 4 || a[2].length == 0)
throw("XMLHttpRequest.open: invalid url: '" + url_ + "'");
if (a[1] != 'http')
throw("XMLHttpRequest.open: unsupported protocol: '" + a[1] + "'");
if (method_ != "GET" && method_ != "POST")
throw("XMLHttpRequest.open: unsupported method: '" + method_ + "'");
method = method_;
url = url_;
if (typeof async_ == 'boolean' && async_ == false)
async = false;
if (user_) {
if (!pass_) pass_ = '';
auth = encodeB64(user_ + ':' + pass_);
}
path = '/' + a[3];
var b = a[2].split(':');
host = b[0];
port = (b.length>1)?b[1]:80;
stm = new Stream('net://' + host + ':' + port);
this_ = this;
hdrs['User-Agent'] = 'JSDB/
1.8.0.7';
hdrs['Accept'] = '*/*';
hdrs['Host'] = host;
this.readyState = 0;
this.responseText = null;
}
this.setRequestHeader = function(name_,value_)
{
hdrs[name_] = '' + value_;
}
this.send = function(data_)
{
if (stm == null) throw("XMLHttpRequest.send: not connected");
response.ready = 1;
response.text = null;
this.readyState = response.ready;
this.responseText = response.text;
if (auth)
hdrs['Authorization'] = 'Basic ' + auth;
if (data_)
hdrs['Content-Length'] = ('' + data_).length;
else
delete hdrs['Content-Length'];
var request = method + ' ' + path + ' HTTP/1.1\r\n';
for (var i in hdrs)
request += i + ': ' + hdrs[i] + '\r\n';
request += '\r\n';
stm.write(request);
if (data_)
stm.write('' + data_);
response.ready = 2;
this.readyState = response.ready;
if (!async)
while (!response.get());
}
this.abort = function()
{
if (stm) stm.close();
stm = null;
this_ = null;
}
response.get = function()
{
if (stm == null) throw("XMLHttpRequest.response.get: not connected");
if (response.ready < 2)
throw("XMLHttpRequest.response.get: request not sent");
if (response.ready == 4) return true;
if (!stm.canRead) return false;
if (response.text == null) {
response.hdrs = new Record('','\r\n');
var cnt = stm.readMIME(response.hdrs);
response.cl = response.hdrs.get('Content-Length');
response.te = response.hdrs.get('Transfer-Encoding');
response.text = '';
response.ks = '';
response.kl = 0;
response.ready = 3;
this_.readyState = response.ready;
}
if (
response.cl && !isNaN(
response.cl)) {
while (
response.cl > 0) {
if (!stm.canRead) return false;
var s = stm.read(
response.cl);
response.cl -= s.length;
response.text += s;
}
}
else
if (response.te && response.te == 'chunked') {
for (;;) { // De-chunk
if (!stm.canRead) return false;
if (response.kl == 0) {
var s = response.ks;
if (s.length == 0 || s[s.length - 1] != '\r')
s = response.ks += stm.readln('\n');
if (s.length == 0 || s[s.length - 1] != '\r')
continue;
response.kl = parseInt(s.substring(0,s.length - 1),16);
response.ks = '';
}
if (response.kl == 0) {
stm.read(2);
break;
}
var t = stm.read(response.kl);
response.kl -= t.length;
response.text += t;
if (response.kl == 0)
stm.read(2);
}
}
else
response.text = '';
response.ready = 4;
this_.readyState = response.ready;
this_.responseText = response.text;
return true; // Done
}
this.process = function()
{
return response.get();
}
}
/* test_xmlhttprequest.js
* Copyright (C) 2014 gilado
*/
println("var req = new XMLHttpRequest()");
var req = new XMLHttpRequest();
println("readyState: " + req.readyState);
println("\n------------------------------------------------------------\n");
println("req.open('GET','
http://www.jsdb.org/index.html')");
req.open('GET','
http://www.jsdb.org/index.html');
println("readyState: " + req.readyState);
println("req.send()");
req.send();
println("readyState: " + req.readyState);
println("while (!req.process())");
while (!req.process());
println("readyState: " + req.readyState);
println("responseText: " + req.responseText);
println("\n------------------------------------------------------------\n");
println("req.open('GET','
http://www.jsdb.org/jsdb.gif',false)");
req.open('GET','
http://www.jsdb.org/jsdb.gif',false);
println("readyState: " + req.readyState);
println("req.send()");
req.send();
println("readyState: " + req.readyState);
println("responseText (length " + req.responseText.length + "): " + req.responseText);
println("\n------------------------------------------------------------\n");
println("req.open('GET','
http://www.jsdb.org/login',false,'username','password')");
req.open('GET','
http://www.jsdb.org/login',false,'username','password');
println("readyState: " + req.readyState);
println("req.send()");
req.send();
println("readyState: " + req.readyState);
println("responseText: " + req.responseText);