Created
April 13, 2013 14:37
-
-
Save hasenj/5378660 to your computer and use it in GitHub Desktop.
Revisions
-
hasenj created this gist
Apr 13, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,189 @@ echo = function(areq) { console.log(areq.response) }; requests = (function() { var module = {}; var AsyncRequest = XMLHttpRequest; // takes a dict and returns a string "a=b&c=d" var toUrlParams = function(dict) { var res = []; for(var key in dict) { var value = encodeURIComponent(dict[key]) res.push(key + "=" + value); } return res.join("&"); } // takes a path and a params dict and returns a string "/path/?param1=val1¶m2=val2" var makeUrl = function(path, params) { var params = toUrlParams(params); if(params) { return path + "?" + params; } else { return path; } } // get the hostname from a url/path the same way that the hostname is extracted from the location in window.href.hostname // from: http://stackoverflow.com/a/8498668/35364 var pathHost = function(url) { var a = document.createElement('a'); a.href = url; return a.hostname; } // call all the callbacks/hooks without failing var call = function(callback_array, this_arg, args) { for(var index = 0; index < callback_array.length; index++) { try { // call the callback using fn.apply callback_array[index].apply(this_arg, args); } catch(e) { // pass console.log("callback error"); } } } var before_hooks = []; module.before_send = function(fn) { before_hooks.push(fn); return module; // allow chaining; } // constructor var JsonRequest = function(pmethod, ppath) { var self = this; var method = pmethod.toUpperCase(); var path = ppath; var data = {}; var params = {}; var headers = []; var success_hooks = []; var error_hooks = []; var complete_hooks = []; // this one is a getter only! self.path = function() { return path; } self.method = function() { return method; } // the rest are only setters self.header = function(key, value) { var h = {key: key, value: value}; headers.push(h); return self; } self.data = function(pdata) { data = pdata; return self; } self.params = function(pparams) { params = pparams; return self; } self.success = function(fn) { success_hooks.push(fn); return self; } self.error = function(fn) { error_hooks.push(fn); return self; } self.complete = function(fn) { complete_hooks.push(fn); return self; } self.send = function() { // call before_send hooks // we must call it here before we start building the request and setting headers, etc // because these hooks are meant for addings headers, etc call(before_hooks, self, [self]); var areq = new AsyncRequest(); var url = makeUrl(path, params); areq.open(method, url); // force json areq.setRequestHeader("Content-Type", "application/json"); // set the ajax header areq.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // set headers // Traverse the headers list by the order of insertion // Note: Do this after forcing the json header so that users can override it for(var i = 0; i < headers.length; i++) { var header = headers[i]; areq.setRequestHeader(header.key, header.value) } // TODO: have option to send datatypes other than json? var json_data = JSON.stringify(data); areq.send(json_data); areq.onreadystatechange = function() { if(areq.readyState == areq.DONE) { call(complete_hooks, areq, [areq]); if(areq.status == 200) { call(success_hooks, areq, [areq]); } else { call(error_hooks, areq, [areq]); } } } return self; } // utilities/helpers /// Check if the path is going to a different domain self.isCrossOrigin = function() { if(path.charAt(0) === "/" && path.charAt(1) !== "/") { return false; } // path has a domain; check if it's different from current domain if(pathHost(path) == window.location.hostname) { return false; } // has a host but not the same as this one; so it's cross-domain return true; } self.isSameOrigin = function() { return !self.isCrossOrigin(); } } module.request = function(method, path) { return new JsonRequest(method, path); } module.get = function(path) { return module.request("get", path); } module.post = function(path) { return module.request("post", path); } module.put = function(path) { return module.request("put", path); } module.del = function(path) { return module.request("delete", path); } return module; }());