UNPKG

ahr2

Version:

An Abstract Http Request for Node.JS (http/https) and the Browser (XMLHttpRequeuest2). For `npm install ahr2` for Node and `pakmanager build` for Ender / Pakmanager. It should be required as `var request = require('ahr2')`

128 lines (111 loc) 3.37 kB
/*jshint strict:true node:true es5:true onevar:true laxcomma:true laxbreak:true eqeqeq:true immed:true latedef:true*/ /* loadstart; progress; abort; error; load; timeout; loadend; */ (function () { "use strict"; function browserJsonpClient(req, res) { // TODO check for Same-domain / XHR2/CORS support // before attempting to insert script tag // Those support headers and such, which are good var options = req.userOptions , cbkey = options.jsonpCallback , window = require('window') , document = require('document') , script = document.createElement("script") , head = document.getElementsByTagName("head")[0] || document.documentElement , addParamsToUri = require('../utils').addParamsToUri , timeout , fulfilled; // TODO move this logic elsewhere into the emitter // cleanup: cleanup window and dom function cleanup() { fulfilled = true; window[cbkey] = undefined; try { delete window[cbkey]; // may have already been removed head.removeChild(script); } catch(e) {} } function abortRequest() { req.emit('abort'); cleanup(); } function abortResponse() { res.emit('abort'); cleanup(); } function prepareResponse() { // Sanatize data, Send, Cleanup function onSuccess(data) { var ev = { lengthComputable: false, loaded: 1, total: 1 }; if (fulfilled) { return; } clearTimeout(timeout); res.emit('loadstart', ev); // sanitize data = JSON.parse(JSON.stringify(data)); res.emit('progress', ev); ev.target = { result: data }; res.emit('load', ev); cleanup(); } function onTimeout() { res.emit('timeout', {}); res.emit('error', new Error('timeout')); cleanup(); } window[cbkey] = onSuccess; // onError: Set timeout if script tag fails to load if (options.timeout) { //timeout = setTimeout(onTimeout, options.timeout); } } function makeRequest() { var ev = {} , jsonp = {}; function onError(ev) { res.emit('error', ev); } // ?search=kittens&jsonp=jsonp123456 jsonp[options.jsonp] = options.jsonpCallback; options.href = addParamsToUri(options.href, jsonp); // Insert JSONP script into the DOM // set script source to the service that responds with thepadded JSON data req.emit('loadstart', ev); try { script.setAttribute("type", "text/javascript"); script.setAttribute("async", "async"); script.setAttribute("src", options.href); // Note that this only works in some browsers, // but it's better than nothing script.onerror = onError; head.insertBefore(script, head.firstChild); } catch(e) { req.emit('error', e); } // failsafe cleanup setTimeout(cleanup, 2 * 60 * 1000); // a moot point since the "load" occurs so quickly req.emit('progress', ev); req.emit('load', ev); } setTimeout(makeRequest, 0); req.abort = abortRequest; res.abort = abortResponse; prepareResponse(); return res; } module.exports = browserJsonpClient; }());