/**
* jQuery.AJAX
*
* A plug-in to handle AJAX form requests
*
* Features:
* - caching
* - context of request
* - type (json, jsonp, xml and script supported)
* - success callback
* - error callback
* - before submit callback
* - X-Alt-Referer headers
* - Content-MD5 headers
*
* Fork me @ https://www.github.com/jas-/jQuery.AJAX
*
* Author: Jason Gerfen <jason.gerfen@gmail.com>
* License: GPL (see LICENSE)
*
*/
(function($){
/**
* @function jQuery.AJAX
* @abstract Handle AJAX form requests
* @param options object options object for specific operations
* cache, debug, callback, context, preCallback
*/
$.fn.AJAX = function(method) {
/**
* @object defaults
* @abstract Default set of options for plug-in
*/
var defaults = {
formID: $(this),
appID: 'jQuery.AJAX',
cache: true,
context: $(this),
type: 'json',
clickjack: 'deny',
xss: true,
proxy: 'http',
strict: true,
callback: function(){},
preCallback: function(){},
errCallback: function(){}
};
/**
* @object methods
* @abstract Plug-in methods
*/
var methods = {
/**
* @function init
* @abstract Performs XMLHttpRequest by first setting
* configurable parameters, setting custom X-Alt-Referer
* header and CRC header via Content-MD5 of serialized form
* data and optionally performs pre-, post and error callbacks
*/
init: function(o){
var opts = $.extend({}, defaults, o);
$('#'+opts.formID.attr('id')).on('submit', function(e){
e.preventDefault();
var _data = _serialize(_gE(opts));
$.ajax({
form: opts.formID.attr('id'),
url: opts.formID.attr('action'),
type: opts.formID.attr('method'),
data: _data,
context: opts.context,
cache: opts.cache,
crossDomain: (opts.type==='jsonp') ? true : false,
dataType: opts.type,
beforeSend: function(xhr){
xhr.setRequestHeader('X-Alt-Referer', opts.appID);
xhr.setRequestHeader('X-Forwarded-Proto', opts.proxy);
xhr.setRequestHeader('X-Frame-Options', opts.clickjack);
if (opts.xss){
xhr.setRequestHeader('X-XSS-Protection', '1;mode=block');
}
if (opts.formID.serialize()){
xhr.setRequestHeader('Content-MD5', base64.encode(md5(_data)));
} else {
xhr.setRequestHeader('Content-MD5', base64.encode(md5(o.appID)));
}
((opts.preCallback)&&($.isFunction(opts.preCallback))) ?
opts.preCallback(xhr) : false;
},
success: function(x, status, xhr){
((opts.strict)&&(opts.strict==true)&&(_vE(xhr, opts)==true)&&
(opts.callback)&&($.isFunction(opts.callback))) ?
opts.callback.call(x) :
((opts.strict)&&(opts.strict==true)&&(_vE(xhr, opts)==false)&&
(opts.errCallback)&&($.isFunction(opts.errCallback))) ?
opts.errCallback.call(x) : console.log(x);
},
error: function(xhr, status, error){
((opts.errCallback)&&($.isFunction(opts.errCallback))) ?
opts.errCallback.call(xhr, status, error) : false;
}
});
return true;
});
}
};
/**
* @function _vE
* @abstract Performs header validation if transaction type is set
* to strict (empty = false)
*/
var _vE = function(xhr, o){
return ((vStr(xhr.getResponseHeader('X-Alt-Referer')))&&
(vStr(xhr.getResponseHeader('X-Forwarded-Proto')))&&
(vStr(xhr.getResponseHeader('X-Frame-Options')))&&
(vStr(xhr.getResponseHeader('X-XSS-Protection')))) ? _vM(xhr, o) : false;
}
/**
* @function _vM
* @abstract Performs header validation if transaction type is set
* to strict (opts != headers = false)
*/
var _vM = function(xhr, o){
var xss = (o.xss) ? '1;mode=block' : '0';
return ((xhr.getResponseHeader('X-Alt-Referer')==o.appID)&&
(xhr.getResponseHeader('X-Forwarded-Proto')==o.proxy)&&
(xhr.getResponseHeader('X-Frame-Options')==o.clickjack)&&
(xhr.getResponseHeader('X-XSS-Protection')==xss)) ? true : false;
}
/**
* @function md5
* @abstract Performs MD5 hash of serialized form data. The data is then
* to be used on the server as a checksum
* @author http://www.webtoolkit.info/javascript-md5.html
*/
var md5 = function(v){
function RotateLeft(lValue, iShiftBits){
return (lValue<<iShiftBits)|(lValue>>>(32-iShiftBits));
}
function AddUnsigned(lX,lY){
var lX4,lY4,lX8,lY8,lResult;
lX8=(lX&0x80000000);
lY8=(lY&0x80000000);
lX4=(lX&0x40000000);
lY4=(lY&0x40000000);
lResult=(lX&0x3FFFFFFF)+(lY&0x3FFFFFFF);
if (lX4&lY4){
return (lResult^0x80000000^lX8^lY8);
}
if (lX4|lY4){
if (lResult&0x40000000){
return (lResult^0xC0000000^lX8^lY8);
}else{
return (lResult^0x40000000^lX8^lY8);
}
}else{
return (lResult^lX8^lY8);
}
}
function F(x,y,z){return (x&y)|((~x)&z);}
function G(x,y,z){return (x&z)|(y&(~z));}
function H(x,y,z){return (x^y^z);}
function I(x,y,z){return (y^(x|(~z)));}
function FF(a,b,c,d,x,s,ac) {
a=AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function GG(a,b,c,d,x,s,ac) {
a=AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function HH(a,b,c,d,x,s,ac) {
a=AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function II(a,b,c,d,x,s,ac) {
a=AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function ConvertToWordArray(string) {
var lWordCount;
var lMessageLength = string.length;
var lNumberOfWords_temp1=lMessageLength + 8;
var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
var lWordArray=Array(lNumberOfWords-1);
var lBytePosition = 0;
var lByteCount = 0;
while ( lByteCount < lMessageLength ) {
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
lWordArray[lNumberOfWords-2] = lMessageLength<<3;
lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
return lWordArray;
}
function WordToHex(lValue) {
var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
for (lCount = 0;lCount<=3;lCount++) {
lByte = (lValue>>>(lCount*8)) & 255;
WordToHexValue_temp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
}
return WordToHexValue;
}
function Utf8Encode(string){
return utf8.encode(string);
}
var x=Array();
var k,AA,BB,CC,DD,a,b,c,d;
var S11=7, S12=12, S13=17, S14=22;
var S21=5, S22=9 , S23=14, S24=20;
var S31=4, S32=11, S33=16, S34=23;
var S41=6, S42=10, S43=15, S44=21;
string = Utf8Encode(v);
x = ConvertToWordArray(string);
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k=0;k<x.length;k+=16){
AA=a; BB=b; CC=c; DD=d;
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
a=AddUnsigned(a,AA);
b=AddUnsigned(b,BB);
c=AddUnsigned(c,CC);
d=AddUnsigned(d,DD);
}
var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
return temp.toLowerCase();
}
/**
* @function base64
* @abstract Performs base64 encoding of argument by first encoding in
* a strict UTF8 format
* @author http://www.webtoolkit.info/javascript-base64.html
*/
var base64 = {
key: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(v){
var c1, c2, c3, e1, e2, e3, e4;
var i=0; var r='';
v=utf8.encode(v);
while (i<v.length){
c1=v.charCodeAt(i++);
c2=v.charCodeAt(i++);
c3=v.charCodeAt(i++);
e1=c1>>2;
e2=((c1&3)<<4)|(c2>>4);
e3=((c2&15)<<2)|(c3>>6);
e4=c3&63;
if (isNaN(c2)){
e3=e4=64;
}else if (isNaN(c3)){
e4=64;
}
r=r+this.key.charAt(e1)+this.key.charAt(e2)+this.key.charAt(e3)+this.key.charAt(e4);
}
return r;
}
}
/**
* @function utf8
* @abstract Helps perform encoding of specified data
* @author http://www.webtoolkit.info/javascript-base64.html
*/
var utf8 = {
encode: function(v){
v=v.replace(/\r\n/g,"\n");
var r='';
for (var n=0; n<v.length; n++){
var c=v.charCodeAt(n);
if (c<128){
r += String.fromCharCode(c);
}else if((c>127)&&(c<2048)){
r += String.fromCharCode((c>>6)|192);
r += String.fromCharCode((c&63)|128);
}else {
r += String.fromCharCode((c>>12)|224);
r += String.fromCharCode(((c>>6)&63)|128);
r += String.fromCharCode((c&63)|128);
}
}
return r;
}
}
/**
* @function _gE
* @abstract Generates object of specified DOM form element that are non-null
*/
var _gE = function(opts){
var obj={};
$.each($(':input, input:radio:selected, input:checkbox:checked, textarea'), function(k,v){
if ((vStr(v.value))&&(vStr(v.name))){
obj[v.name] = v.value;
}
});
return obj;
}
/**
* @function _serialize
* @abstract Create serialized string of object
*/
var _serialize = function(obj){
if (szCk(obj)>0){
var x='';
$.each(obj, function(a, b){
if (typeof b==='object'){
_serialize(b);
} else {
x+=a+'='+b+'&';
}
});
x = x.substring(0, x.length-1);
} else {
x = false;
}
return x;
}
/**
* @function szCk
* @abstract Performs a check on object sizes
*/
var szCk = function(obj){
var n = 0;
$.each(obj, function(k, v){
if (obj.hasOwnProperty(k)) n++;
});
return n;
}
/**
* @function vStr
* @abstract Function used combine string checking functions
*/
var vStr = function(x){
return ((x===false)||(x.length===0)||(!x)||(x===null)||
(x==='')||(typeof x==='undefined')) ? false : true;
}
/* robot, do something */
if (methods[method]){
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if ((typeof method==='object')||(!method)){
return methods.init.apply(this, arguments);
} else {
console.log('Method '+method+' does not exist');
}
};
})(jQuery);
|