Created
May 4, 2012 06:34
-
-
Save swvitaliy/2592618 to your computer and use it in GitHub Desktop.
js cross domain request (script src)
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 characters
/* | |
cross domain request ( script src) | |
todo: | |
- Исправить вызов события complete | |
- Не создавать объект запроса сразу, а искать в пуле и инициализировать | |
найденный актуальными значениями полей объекта xdr и входными параметрами | |
( или создавать новый, если не был найден ) | |
- Исправить удаление переменной результата ( сейчас удаляется весь объект, | |
с которого начинается путь к ней ) | |
@created: 4.05.12 | |
@author: swvitaliy ([email protected]) | |
*/ | |
var xdr = xdr || {} | |
;(function(xdr) | |
{ | |
function XdrRequest(config) | |
{ | |
var defaults = | |
{ | |
container:'head', | |
scriptClass:'xdr', | |
timeout: 30, // seconds | |
waitDelay: 50 // milliseconds | |
}; | |
var now = (new Date()).getTime(); | |
this.scriptClass = config.scriptClass || defaults.scriptClass; | |
this.proxyUrl = config.proxyUrl; | |
this.requestUri = config.uri; | |
this.requestData = config.data; | |
this.timeout = config.timeout || defaults.timeout; | |
this.container = config.container || defaults.container; | |
this.responseVarName = config.responseVarName.replace('.', '_'); | |
this.waitDelay = config.waitDelay || defaults.waitDelay; | |
this.events = | |
{ | |
success:config.success || null, | |
complete:config.complete || null, | |
error:config.error || null, | |
continue:config.continue || null | |
}; | |
this.context = config.context || null; | |
this.init(); | |
if (config.start) | |
{ | |
this.open(); | |
} | |
} | |
XdrRequest.prototype = | |
{ | |
init: function() | |
{ | |
this.request = { script:null }; | |
this.response = { body:null }; | |
}, | |
opened:function() | |
{ | |
return this.request.script !== null; | |
}, | |
open: function() | |
{ | |
if ( this.opened() ) | |
{ | |
return false; | |
} | |
this._makeRequest(); | |
this._startWaiting(); | |
}, | |
_makeRequest: function() | |
{ | |
var container = this.container, | |
proxy = this.proxyUrl, | |
responseVarName = this.responseVarName; | |
function queryArray(name, params) | |
{ | |
var i, r = {}; | |
for ( i in params) | |
{ | |
if (params.hasOwnProperty(i)) | |
{ | |
r[name + '[' + i + ']'] = params[i]; | |
} | |
} | |
return r; | |
} | |
function extendObj(properties) | |
{ | |
var i; | |
for ( i in properties) | |
{ | |
if ( properties.hasOwnProperty(i) ) | |
{ | |
this[i] = properties[i]; | |
} | |
} | |
} | |
function httpBuildQuery(params) | |
{ | |
var i, r = []; | |
for ( i in params) | |
{ | |
if ( params.hasOwnProperty(i) ) | |
{ | |
r.push(i + '=' + encodeURIComponent(params[i])); | |
} | |
} | |
return r.join('&'); | |
} | |
function appendScriptToContainer(uri, params, attributes) | |
{ | |
if (typeof container === 'string') | |
{ | |
container = $(container); | |
} | |
if (container instanceof jQuery) | |
{ | |
container = container.get(0); | |
} | |
params = queryArray('query', params); | |
params = httpBuildQuery(params); | |
var script= document.createElement('script'); | |
script.type= 'text/javascript'; | |
script.src= proxy + '?responseVarName=' + responseVarName + '&uri=' + uri + '&' + params; | |
if (attributes) | |
{ | |
extendObj.apply(script, [attributes]); | |
} | |
container.appendChild(script); | |
return script; | |
} | |
this.request.script = | |
appendScriptToContainer(encodeURIComponent(this.requestUri), this.requestData, | |
{ | |
class:this.scriptClass, | |
id:this.scriptClass + '_' + (new Date()).getTime() | |
}); | |
}, | |
_startWaiting: function() | |
{ | |
var thisObj = this, | |
startTime = (new Date()).getTime(), | |
timeout = this.timeout, | |
responseVar = this.responseVarName, | |
response = this.response, | |
events = this.events, | |
context = this.context; | |
if ( eval( 'window.' + responseVar ) !== undefined ) | |
{ | |
throw "xdr.Request.open variable \"" + 'window.' + responseVar + "\" already exists"; | |
} | |
function sendEvent(ev) | |
{ | |
if ( !events.hasOwnProperty(ev) ) | |
{ | |
throw 'xdr.XdrRequest - send undefined event ({ev})'.replace('{ev}', ev) | |
} | |
if ( !events[ev] ) | |
{ | |
return false; | |
} | |
var evArgs = [].slice.apply(arguments, [1]); | |
events[ev].apply(context, [thisObj].concat(evArgs)); | |
return true; | |
} | |
function waitForResponse() | |
{ | |
var val = eval( 'window.' + responseVar ); | |
if ( val !== undefined ) | |
{ | |
response.body = val; | |
sendEvent('complete'); | |
thisObj.close(); | |
sendEvent('success', val); | |
return true; | |
} | |
var now = (new Date()).getTime(); | |
if ( (now - startTime) / 1000 >= timeout ) | |
{ | |
sendEvent('complete'); | |
thisObj.close(); | |
sendEvent('error', { errorType: 'timeout' }); | |
} | |
else | |
{ | |
sendEvent('continue'); | |
setTimeout(waitForResponse, this.waitDelay); | |
} | |
return false; | |
} | |
waitForResponse(); | |
}, | |
close: function() | |
{ | |
if ( !this.opened() ) | |
{ | |
return false; | |
} | |
this._removeResponseVar(); | |
var $scriptRequest = $(this.request.script); | |
if ( !$scriptRequest.length ) | |
{ | |
return false; | |
} | |
$scriptRequest.remove(); | |
this.request.script = null; | |
return true; | |
}, | |
_removeResponseVar: function() | |
{ | |
var name, str = this.responseVarName, | |
a = str.indexOf('.'), | |
b = str.indexOf('['), | |
pos = []; | |
if ( a >= 0 ) pos.push(a); | |
if ( b >= 0 ) pos.push(b); | |
name = ( pos.length === 0 ) ? str : | |
str.slice(0, Math.max.apply(null, pos)); | |
delete window[name]; | |
return true; | |
} | |
}; | |
/* api functions & properties */ | |
xdr.timeout = 30; | |
xdr.scriptClass = 'xdr_' + (new Date()).getTime(); | |
xdr.container = 'head'; | |
xdr.proxyUrl = 'http://your_domain.com/proxy/url/'; | |
xdr.responseVarName = 'replaceThisLineInTheNameOfTheVariableResponse'; | |
xdr.waitDelay = 50; | |
xdr.Request = XdrRequest; | |
xdr.requests = []; | |
xdr.makeRequest = function(uri, data, success, error) | |
{ | |
var request = new XdrRequest({ | |
timeout:this.timeout, | |
scriptClass:this.scriptClass, | |
container:this.container, | |
proxyUrl:this.proxyUrl, | |
responseVarName:this.responseVarName + (new Date).getTime() + Math.round(9999999999999 * Math.random()), | |
waitDelay:this.waitDelay, | |
uri:uri, | |
data:data, | |
success:success, | |
error:error, | |
start:true | |
}); | |
this.requests.push(request); | |
return request; | |
}; | |
})(xdr); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment