Skip to content

Instantly share code, notes, and snippets.

@zenhob
Created March 12, 2013 20:18
Show Gist options
  • Save zenhob/5146625 to your computer and use it in GitHub Desktop.
Save zenhob/5146625 to your computer and use it in GitHub Desktop.
JQuery-alike JSON client API. Includes promises and cross-browser compatibility.
define('json-client', function() {
var JSON_KEY;
var API_BASE = '';
var validResponses = {
200: true,
201: true,
204: true
};
var invalidResponses = {
400: true,
401: true,
404: true,
500: true
};
var XMLHttpFactories = [
function() {
return new XMLHttpRequest();
},
function() {
return new ActiveXObject('Msxml2.XMLHTTP');
},
function() {
return new ActiveXObject('Msxml3.XMLHTTP');
},
function() {
return new ActiveXObject('Microsoft.XMLHTTP');
}
];
function createXMLHTTPObject() {
var xmlhttp = false;
for (var i = 0; i < XMLHttpFactories.length; i++) {
try {
xmlhttp = XMLHttpFactories[i]();
} catch (e) {
continue;
}
break;
}
return xmlhttp;
}
function xhr(options) {
var success = options.success || function() {};
var error = options.error || function() {};
var req = createXMLHTTPObject();
var promise = {
promises: {success:[],failure:[]},
then: function (success, failure) {
if (success) this.promises.success.push(success);
if (failure) this.promises.failure.push(failure);
return this;
},
fail: function (response) {
for (var i = 0; i < this.promises.failure.length; i++) {
this.promises.failure[i](response);
}
},
succeed: function (response) {
for (var i = 0; i < this.promises.success.length; i++) {
this.promises.success[i](response);
}
}
}
promise.then(success, error);
req.open(options.method, API_BASE + options.url, true);
options.headers = options.headers || {};
options.headers['Content-Type'] = 'application/json';
options.headers['Accept'] = 'application/json';
if (JSON_KEY) {
options.headers['X-JSON-Key'] = JSON_KEY;
}
for (var k in options.headers) {
req.setRequestHeader(k, options.headers[k]);
}
req.onreadystatechange = function() {
if (req.readyState !== 4) {
return;
}
if (req.status == 0) {
promise.fail('Server failed to respond.');
return;
}
if ((req.status in invalidResponses) && !(req.status in validResponses)) {
var response = req.responseText;
try {
response = JSON.parse(response);
promise.fail(response);
} catch(e) {
promise.fail('Internal failure: expected JSON.');
}
return;
}
if (req.getResponseHeader('X-New-JSON-Key')) {
JSON_KEY = req.getResponseHeader('X-New-JSON-Key');
}
var response = req.responseText;
response = JSON.parse(response);
promise.succeed(response);
};
if (req.readyState === 4) {
return;
}
req.send(options.data || null);
return promise;
}
function get(options) {
options.method = 'GET';
return xhr(options);
}
function post(options) {
options.method = 'POST';
options.data = JSON.stringify(options.data || {});
return xhr(options);
}
function put(options) {
options.method = 'PUT';
options.data = JSON.stringify(options.data || {});
return xhr(options);
}
return {
get: get,
post: post,
put: put
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment