Created
August 24, 2008 12:24
-
-
Save snj14/6981 to your computer and use it in GitHub Desktop.
XHR
This file contains 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 characters
// XHR -- XMLHttpRequest | |
// Argmunets | |
// | |
// url | |
// method | |
// data | |
// headers | |
// Accept | |
// Referer | |
// User-Agent etc... | |
// onload | |
// onerror | |
// onreadeychange | |
// async (default: true) | |
// Arguments of onload/onerror | |
// | |
// channel | |
// responseText | |
// responseHeaders | |
// requestHeaders | |
// status | |
// finalUrl | |
// etc... | |
// TODO: | |
// authentication | |
// Example | |
/* | |
var opt = { | |
url : 'http://localhost/index.rdf' | |
, method : 'head' | |
, headers : { | |
'Referer' : 'http://example.com/referer' | |
, 'User-Agent' : 'Mozilla/5.0 foo bar baz' | |
} | |
, onload : function(response){ | |
alert('onload \n\n' + response.responseXML) | |
alert('onload \n\n' + response.requestHeaders) | |
} | |
, onerror : function(response){ | |
alert('onerror \n\n' + response.responseXML) | |
} | |
} | |
XHR(opt); | |
*/ | |
function XHR({method,url,headers,data,onload,onerror,onreadystatechange,overrideMimeType,async}){ | |
const Ci = Components.interfaces; | |
const Cc = Components.classes; | |
async = (typeof async == 'undefined') ? true : !!async; | |
var cancel = false; | |
var xhr = new XMLHttpRequest(); | |
xhr.mozBackgroundRequest = async; | |
xhr.open(method || (method = data ? "post" : "get"), url, async); | |
if(overrideMimeType) xhr.overrideMimeType(overrideMimeType); | |
xhr.onload = function(){ | |
addHeadersInfo(); | |
if(onload && !cancel) onload(xhr); | |
}; | |
xhr.onerror = function(){ | |
addHeadersInfo(); | |
if(onerror && !cancel) onerror(xhr); | |
}; | |
if(method == "post") xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); | |
var referrer; | |
if(headers){ | |
for(var header in headers){ | |
if(headers.hasOwnProperty(header)){ | |
if(header == "Referer"){ | |
referrer = headers[header]; | |
}else{ | |
xhr.setRequestHeader(header, headers[header]); | |
} | |
} | |
} | |
} | |
if(referrer){ | |
var RefererSetter = { | |
observe: function(aSubject, aTopic, aData){ | |
if ((aTopic == 'http-on-modify-request') | |
&& (typeof Components != "undefined")) { | |
aSubject.QueryInterface(Ci.nsIHttpChannel); | |
if(aSubject.originalURI.spec == url){ | |
observer.removeObserver(RefererSetter, aTopic, false); | |
aSubject.setRequestHeader('Referer',referrer,false); | |
} | |
} | |
} | |
}; | |
var observer = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); | |
observer.addObserver(RefererSetter, "http-on-modify-request", false); | |
} | |
function addHeadersInfo(){ | |
if(!xhr.channel.contentCharset && !overrideMimeType){ // wrong charset | |
var mimeType = getEncoding(xhr.responseText); | |
if(mimeType){ | |
cancel = true; | |
XHR({ method: method | |
, url: url | |
, headers: headers | |
, data: data | |
, onload: onload | |
, onerror: onerror | |
, onreadystatechange: onreadystatechange | |
, overrideMimeType: mimeType | |
, async: async | |
}); | |
return; | |
} | |
} | |
xhr.channel.QueryInterface(Ci.nsIHttpChannel); | |
xhr.responseHeaders = {}; | |
xhr.channel.visitResponseHeaders({visitHeader: function(aHeader,aValue){xhr.responseHeaders[aHeader] = aValue}}); | |
xhr.requestHeaders = {}; | |
xhr.channel.visitRequestHeaders({visitHeader: function(aHeader,aValue){xhr.requestHeaders[aHeader] = aValue}}); | |
xhr.finalUrl = xhr.channel.URI.spec; | |
} | |
function getEncoding(text){ | |
var matched = text.match(new RegExp("<meta.+?http-equiv.+?Content-Type.+?content=([\"'])([^\\1]+?)\\1",'i')); | |
return (matched && !matched[2].match(/UTF-8/i) && matched[2]); | |
} | |
xhr.send(data || null); | |
return xhr; | |
} | |
XHR.Test = function(){ | |
XHR({ | |
// url: "http://white.s151.xrea.com/wiki/index.php?cmd=edit&page=FrontPage" // test 401 | |
url: "http://white.s151.xrea.com/blog/" | |
, onload: function(response){log('XHR load',response)} | |
, onerror: function(response){log('XHR error',response)} | |
, headers: {'Referer':'http://example.org/referrer'} | |
}); | |
} | |
// XHR.JSDeferred --- | |
XHR.JSDeferred = function(opt){ | |
var d = Deferred(); | |
var stop = false; | |
try{ | |
opt.onload = function(res){ | |
if(stop) return; | |
d.call(res); | |
} | |
opt.onerror = function(res){ d.fail(res); } | |
var xhr = XHR(opt); | |
d.canceller = function(){ xhr.abort(); } | |
}catch(e){ | |
d.fail(e); | |
} | |
return d; | |
} | |
XHR.JSDeferred.Test = function(){ | |
XHR.JSDeferred({ url: "http://white.s151.xrea.com/blog/" | |
, headers: {'Referer':'http://example.org/referrer'} | |
}) | |
.next(function(d){ | |
log('XHR.JSDeferred ', d); | |
}) | |
} | |
XHR.JSDeferred.ParallelTest = function(){ | |
Deferred.parallel({ | |
root: XHR.JSDeferred({ url:"http://white.s151.xrea.com/", headers:{'Referer':'http://example.org/referrer'}}) | |
, blog: XHR.JSDeferred({ url:"http://white.s151.xrea.com/blog/", headers:{'Referer':'http://example.org/referrer'}}) | |
, wiki: XHR.JSDeferred({ url:"http://white.s151.xrea.com/wiki/", headers:{'Referer':'http://example.org/referrer'}}) | |
}) | |
.next(function(d){ | |
log('XHR.JSDeferred.ParallelTest ', d); | |
}) | |
} | |
// XHR.Arrow --- | |
XHR.Arrow = function(opt){ | |
return Arrow.fromCPS(function(x, k){ | |
var stop = false; | |
try { | |
opt.onload = function(res){ | |
if(stop) return; | |
k(res); | |
} | |
opt.onerror = function(res){ | |
k(Arrow.Error(xhr)); | |
} | |
XHR(opt); | |
} catch (e) { | |
k(Arrow.Error(e)); | |
} | |
this.cancel = function() { stop = true }; | |
}); | |
} | |
XHR.Arrow.Test = function(){ | |
var arrow = ((XHR.Arrow({url: "http://white.s151.xrea.com/blog/" | |
, headers: {'Referer':'http://example.org/referrer'} | |
})) | |
['>>>'] | |
(Arrow.fromCPS(function(x, k){ | |
log('XHR.Arrow ', x) | |
}))); | |
arrow.run(); | |
} | |
// XHR.ArrowParallel --- | |
XHR.ArrowParallel = function(opts){ | |
var arrow = new Arrow; | |
arrow.cpsFunction = function(x, k) { | |
var arrows = this.arrows; | |
var results = []; | |
var count = arrows.length; | |
for (var i = 0; i < arrows.length; i++) { | |
with ({ i: i }) { | |
arrows[i].callCPS(x, function(y) { results[i] = y; if (!--count) k(results) }); | |
} | |
} | |
} | |
arrow.type = '&&&'; | |
arrow.arrows = opts.map(function(opt){ | |
return XHR.Arrow(opt); | |
}); | |
return arrow; | |
} | |
XHR.ArrowParallel.Test = function(){ | |
((XHR.ArrowParallel([{url: "http://white.s151.xrea.com/"}, | |
{url: "http://white.s151.xrea.com/wiki/"}, | |
{url: "http://white.s151.xrea.com/blog/"}])) | |
['>>>'] | |
(Arrow.fromCPS(function(x, k){ | |
log('xhr response list:', x) | |
}))).run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment