I am new to javascript. I am facing an issue in someone else written code. They have created a security.js file and they are trying to overwrite xmlHTTPRequest (am not sure). attaching the code here.
(function () {
function getXHRObj(baseObj){
var Impl = function(){
this.onreadystatechange = null;
return this;
};
//Impl.prototype.onreadystatechange = null;
// set the prototype of the new constructor
Impl.prototype = baseObj;
//Impl.prototype.constructor = Impl; // does not work in IE
// the object to be returned
var retObj = new Impl();
function isHTTPReq(url){
if(url){
var colIndx = url.indexOf('://');
if((colIndx < 0)
|| (url.substr(0, colIndx).toLowerCase().indexOf('http') == 0))
return true;
}
return false;
}
// customize open to add token in URL
// even POST request should do this since POST may not always have key=value&... data format
retObj.open = function(method, URL, async, user, pwd){
if(isHTTPReq(URL)){
var prefix = (URL.indexOf('?') < 0)? '?' : '&';
URL += (prefix + window.csrfToken);
}
//alert('making ajax to - ' + URL);
Impl.prototype.open(method, URL, async, user, pwd);
};
// customize send
retObj.send = function(body){
/* Register the handler just before "send" to allow reuse of same object */
Impl.prototype.onreadystatechange = function(){
//alert('Impl.prototype.readyState- '+ Impl.prototype.readyState);
// copy the properties to return object
if(Impl.prototype.readyState)
retObj.readyState = Impl.prototype.readyState;
if(Impl.prototype.readyState == 4){
if(Impl.prototype.status)
retObj.status = Impl.prototype.status;
if(Impl.prototype.statusText)
retObj.statusText = Impl.prototype.statusText;
if(Impl.prototype.responseText)
retObj.responseText = Impl.prototype.responseText;
if(Impl.prototype.responseXML)
retObj.responseXML = Impl.prototype.responseXML;
//alert('xml done');
}
// publish event to return object handler
if(retObj.onreadystatechange){
//alert('invoking handler - \n' + retObj.onreadystatechange);
retObj.onreadystatechange();
}else{
//alert('no handler');
}
};
Impl.prototype.send(body);
};
// delegate other methods
/* Redefinition is necessary because IE does not allow inheritance
from native objects */
retObj.abort = function() {
Impl.prototype.abort();
};
retObj.setRequestHeader = function(hdr, val){
Impl.prototype.setRequestHeader(hdr, val);
};
retObj.getResponseHeader = function(hdr){
return Impl.prototype.getResponseHeader(hdr);
};
retObj.getAllResponseHeaders = function(){
return Impl.prototype.getAllResponseHeaders();
};
return retObj;
}
// redefine the XMLttpRequest to use custom definition
if(window.XMLHttpRequest){
var Base_XMLHttpRequest = window.XMLHttpRequest;
window.XMLHttpRequest = function(){
//alert('in new XHR');
return getXHRObj(new Base_XMLHttpRequest());
};
}
// redefine the ActiveXObject to use custom definition
if(window.ActiveXObject) {
var Base_ActiveXObject = window.ActiveXObject;
window.ActiveXObject = function(objType){
//alert('in new ActiveXObj for - ' + objType);
if((objType.toLowerCase() != "microsoft.xmlhttp")
&&(objType.toLowerCase().indexOf("msxml2.xmlhttp") < 0)){
// return the standard impl for non-ajax objects
return new Base_ActiveXObject(objType);
}else{`enter code here`
//alert('returning new impl for ' + objType);
return getXHRObj(new Base_ActiveXObject(objType));
}
};
}
})();
This code is working fine in IE7 & 8, but this is giving error in all other browsers.
IE9 error -
SCRIPT65535: Invalid calling object
security.js, line 71 character 4
Error is pointing to this.onreadystatechange = null;
var Impl = function(){
this.onreadystatechange = null;
return this;
};
Appreciate immediate help.
Thanks!
Related
I'm basically following the accepted answer to this question (Is it possible to ping a server from Javascript?)
Update
It seems to work as expected when the domain is 15 characters long (actually, http:// + 15, but 16 or more causes it to bomb. More details at the bottom.
The issue I'm seeing is that if you're using something that seems like a valid domain, for example http://thisisdefinitelynotarealdomainname.com, it returns an error but the code mentioned considers errors okay (because most should be). Looking at the error event, I'm not sure I see where I could get the HTTP response code (i.e., if it's a 404, consider it invalid).
Here is a jsFiddle showing the problem -- they all display "responded". If you look in the console, the invalid domain returns a 404 error, and the two valid ones (if in chrome console, not sure about the others) show that they were interpreted as an image but transferred as text/html -- is there any way to read either the 404 error, or the mime type?
var pinger = function () {
var ping = function (ip, callback) {
if (!this.inUse) {
this.status = 'unchecked';
this.inUse = true;
this.callback = callback;
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function () {
_that.inUse = false;
_that.callback('responded');
};
this.img.onerror = function (e) {
if (_that.inUse) {
_that.inUse = false;
_that.callback('responded', e);
}
console.log(e);
};
this.start = new Date().getTime();
this.img.src = "http://" + ip + "/?now=" + this.start; // add the current time to work around caching
this.time = setTimeout(function () {
if (_that.inUse) {
_that.inUse = false;
_that.callback('timeout');
}
}, 1500);
}
}
return {
ping: ping
};
}();
(function () {
var output = document.getElementById('output');
var servers = [
'localhost',
'google.com',
'okthisreallydoesntmakeanysense',
'okthisreallydoe',
'thisisashortone',
'thisisabitlonger'
];
servers.forEach(function (server) {
new pinger.ping(server, function (status, e) {
output.innerHTML += server + ': ' + status + '<br />';
});
});
})();
Update
What's even more weird is that it seems to be fine up until 15 characters. I've updated the jsFiddle. See below on ones that respond how I'd expect vs ones that don't. What might cause this?
'localhost',
'google.com',
'okthisreallydoesntmakeanysense', // doesn't work
'okthisreallydoe', // works (15 characters)
'thisisashortone', // works (15 characters)
'thisisabitlonger' // doesn't work (16 characters)
This might help.
function Pinger_ping(ip, callback) {
if(!this.inUse) {
this.inUse = true;
this.callback = callback
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function() {_that.good();};
this.img.onerror = function() {_that.good();};
this.start = new Date().getTime();
this.img.src = "http://" + ip;
this.timer = setTimeout(function() { _that.bad();}, 1500);
}
}
Let me know if it works
This is the code I wrote:
function responseAjax(element, url, loader, data) {
if(request.readyState == 4) {
if(request.status == 200) {
//The response has 2 main parts: the main page element and the javascript that have the text "???PHPTOSCRIPT???" in between
output = request.responseText.split('???PHPTOSCRIPT???');
if (element) document.getElementById(element).innerHTML = output[0];//put first part into element
if (output[1] != "") eval(output[1]); //execute script
//remember the last request
if (typeof(url) !== 'undefined') {
document.cookie = "requestedURL=" + escape(url);
document.cookie = "requestedElement=" + escape(element);
document.cookie = "requestedLoader=" + escape(loader);
document.cookie = "requestedData=" + escape(data);
};
};
};
};
function ajax(url, element, loader, data, remember, async) {
remember = (typeof(remember) === 'undefined') ? false : remember;//remember last request. Default: false
async = (typeof(async) === 'undefined') ? true : async;//handle request asynchronously if true. Default: true
if (loader) document.getElementById(element).innerHTML = loader;
try { request = new XMLHttpRequest(); /* e.g. Firefox */}
catch(err) {
try { request = new ActiveXObject("Msxml2.XMLHTTP"); /* some versions IE */}
catch(err) {
try { request = new ActiveXObject("Microsoft.XMLHTTP"); /* some versions IE */}
catch(err) { request = false;}
}
}
if (request) {
url += "?r=" + parseInt(Math.random()*999999999);//handle the cache problem
//put an array of data into string. Default: null array
data = data || [];
for (var i = 0; i < data.length; i++) {
url += "&" + data[i];
};
request.open("GET", encodeURI(url), async);
url = url.split('?');//get query string for remembered request
request.onreadystatechange = (remember) ? function() {responseAjax(element, url[0], loader, data.join('&'));}
: function() {responseAjax(element)};
request.send(null);
} else {
document.getElementById(element).innerHTML = "<h3>Browser Error</h3>";
};
};
Though I use eval() to handle returned script, the script doesn't work on events after all if I use pure javascript. However, if I use jQuery such as $("#tab-panel").createTabs();, this code works fine.
Can someone please explain why pure javascript on the loaded content of ajax doesn't work?
Additional information: As I said, pure javascipt such as function sent through the ajax content doesn't work on events, however another code such as alert() works fine.
I have the following JavaScript class:
var Server = function(onError)
{
/* public As, onError; */
var that, Key, Headers;
this.__construct = function()
{
that = this;
that.As = false;
that.onError = onError;
that.resetHeaders();
onError = null;
// Here I try to call the parent constructor (it seems I can't).
if(window.XMLHttpRequest)
that.XMLHttpRequest();
else
that.ActiveXObject('Microsoft.XMLHTTP');
}
this.Request = function(File, PostData, Function)
{
var Method, HeaderKey;
if(PostData == null)
Method = 'GET';
else
Method = 'POST';
try
{
that.open(Method, File, that.As);
/* Each request sets X-Requested-With to XMLHttpRequest by default.
If PostData is given, then we treat it's content type as a form.*/
that.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
if(PostData != null)
that.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
for(HeaderKey = 0; HeaderKey < Headers.length; HeaderKey++)
that.setRequestHeader(Headers[ HeaderKey ].Name, Headers[ HeaderKey ].Value);
if(Function != null)
that.onreadystatechange = function()
{
if(that.readyState == 4 && that.status == 200)
Function.call();
}
that.send(PostData);
}
catch(Exception)
{
if(that.onError != null)
that.onError(Exception);
}
}
this.addHeader = function(Name, Value)
{
Headers[ Key ] = {};
Headers[ Key ].Name = Name;
Headers[ Key ].Value = Value;
Key++;
}
this.resetHeaders = function()
{
Headers = [];
Key = 0;
}
this.__construct();
}
if(window.XMLHttpRequest)
Server.prototype = new XMLHttpRequest();
else
Server.prototype = new ActiveXObject('Microsoft.XMLHTTP');
Server.prototype.constructor = Server;
Where I make an inheritance depending on the state of the window.XMLHttpRequest var. In the __construct method I re-check this again for call the parent constructor.
I don't know if this is the correct form, but I would like that anyone could tell me what's wrong in here. By the way, when I check the console in Chrome I get the following exception: "Uncaught TypeError: Object [object Object] has no method 'XMLHttpRequest'", so I assume that it is not identifying the correct reference, however, I can see that all the properties / methods are present when I put the "." in the console, but I can't get access from a internal / external way (this is commenting the parent constructor condition). Thank you, I'll wait for your replies.
I am trying to run multiple Ajax functions on load in a single page which will get data from two different php pages. Both the Ajax functions will then print the retrieved data onto the page from which the ajax function was called. The problem I encountered was that the last function call which I make from the Ajax overrides the first function call, and so only the second function result is showed.
The code for one of the Ajax function (since both of the are very similar to each other):
function favorite_track_request(str){
switch(str){
case 'next_track':
var feed = 'require_fav_track_info';
var offset = track_currentOffset + 5;
if(offset > max_track_range){
offset -= 5;
}
break;
case 'prev_track':
var feed = 'require_fav_track_info';
var offset = track_currentOffset - 5;
if(offset < 0){
offset = 0;
}
break;
default:
var feed = 'require_fav_track_info';
var offset = 0;
}
request = new ajaxRequest()
request.open("GET", "scripts/"+feed+".php?offset="+offset, true)
request.onreadystatechange = function(){
if(this.readyState == 4){
if(this.status == 200){
if(this.responseText != null){
if(request.responseText){
document.getElementById('fav_tracks').innerHTML = request.responseText;
}
}else alert("No data recieved");
}else {
alert("Ajax error: "+this.statusText);
}
}
}
request.send(null);
track_currentOffset = offset;
}
This ajax would then print to <div id="fav_tracks"></div>, however this gets overridden because another call (similar to the Ajax above) is made and that overrides the previous one. Is there any way to stop this?
I built a data handler "class" to manage just such a thing. You are right, the one overrides the other. I haven't investigated it, but it's probabably because your are re-assigning the onEvent that AJAX uses.
Below is the class I built (I know, it's not JQuery... it works). What it does is uses timeouts to "know" when to fire the second and third async request. There probably is a JQuery function that does the same thing.
You would call this by using the below for each AJAX call (giving each call a unique var name):
dataHandler = new DataHandler("[name of datafile to call]");
dataHandler.query['[myQueryName]'] = 'myValue' //this is an Object used to build a query string, if needed, so use as many data pairs as you need
dataHandler.asynchronous(myOnReadyStateChangeFN);//put the fn you want to use for readystatechange as a reference... do not includ the ()
Here's the "class":
function DataHandler(dataFile){
this.dataFile = dataFile;
dataInProgress = false;
this.query = new Object();
this.asynchronous = function(fn){
var thisFunction = this.asynchronous
var rand = Math.floor(Math.random()*100001);
var query, timeOutFunctionString;
if(this.dataInProgress){
timeOutFunctionString = callingObjectName+".asynchronous("+fn+")";
this.thisTimeout = setTimeout(timeOutFunctionString,500);
}else{
dataInProgress = true;
this.assignRequestObject.xmlHttp.onreadystatechange = function () {
fn();
dataInProgress = false;
return;
};
}
query = this.dataFile + '?r=' + rand;
for (var key in this.query) query = query + '&' + key + '=' + this.query[key];
//console.info("DataHandler.asynchronous\nquery = "+query+'\nthis.dataFile = ' + this.dataFile);
this.assignRequestObject.xmlHttp.open('GET', query, true);
this.assignRequestObject.xmlHttp.send(null);
};
this.AssignRequestObject = function() {
try { this.xmlHttp = new XMLHttpRequest() } catch (e) {
try { this.xmlHttp = new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {
try { this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {
alert("Your browser does not support AJAX!");
return false
}
}
}
};
this.assignRequestObject = new this.AssignRequestObject();
};
I want to ask which code I need to write in order to invoke a doGet() in a Java Servlet. Right now the code I had written is:
function(){
var sURL = getUniqueSid("http://localhost:8080/Test/Sample?F=" + f + "&FB=" + fb);
var ret = xmlSyncHttpReq(sURL);
if (ret){
var params = new GG_ContainerParams("General");
var xTarget = params.dataSource;
var xElms = ret.selectNodes("Param");
for (var i=0;i<xElms.length;i++){
var x = xElms(i).cloneNode(true);
var chk = xTarget.selectSingleNode("Param[#Name = \"" + x.getAttribute("Name") + "\"]");
if (chk)xTarget.replaceChild(x,chk);
else xTarget.appendChild(x);
params.redraw();
}
}
function xmlSyncHttpReq(sURL,xmlSend,doThrow){
try{
var xmlhttp = new XMLHttpRequest();//ActiveXObject("Microsoft.XMLHTTP");
sURL = getUniqueSid(sURL);
xmlhttp.Open("GET", sURL, false);
xmlhttp.setRequestHeader("Content-Type", "text/xml");
if (typeof(xmlSend) == "object" && xmlSend != null)xmlSend = xmlSend.xml;
xmlhttp.Send(xmlSend);
if(xmlhttp.responseXML.documentElement){
if (checkErrors(xmlhttp.responseXML))return false;
else return xmlhttp.responseXML.documentElement;
}
xmlhttp = null;
return false;
}catch(e){
if (doThrow)throw e;
else alert(e.description);
return false;
}
}
Thanks in advance,
Tal Tchernihovski.
Pay attention to the JavaScript console in the browser. You should have seen the following error:
Uncaught TypeError: Object #<XMLHttpRequest> has no method 'Open'
JavaScript follows the Java naming conventions, not C# naming conventions. Methods start with lowercase. You need to use open() and send() instead of Open() and Send().
See also:
XMLHttpRequest documentation