XDomainRequest object caching/asynchronous call issue - caching

I have an aspx page on which I am using XDomainRequest object to populate two div(s) with html returned from AJAX response.
I have used Jquery to get the divs and perform "each()" on the retrieved List
var divs = $("div");
divs.each(function(index) {
if (window.XDomainRequest) {
xdr = new XDomainRequest();
if (xdr) {
xdr.onload = function() {
alert("XDR Response - " + xdr.responseText);
var currentDivID = divs[index].attributes["id"].value;
var selectedDiv = $("div[id='" + currentDivID + "']");
if (xdr.responseText == '') selectedDiv.attr("style", "display:none;");
else selectedDiv.append(xdr.responseText);
};
xdr.open("GET", xdrUrl);
try {
xdr.send();
} catch (e) {
alert(e);
}
} else {
alert('Create XDR failed.');
}
} else {
alert('XDR not found on window object .');
}
}
Now, whats happening is , i have two Divs on a page that have different IDs and when this code runs on "$.ready(function(){})" , both requests are asynchronously sent to the server and processed
the result is
1. sometimes the onload get the response for the second div in both div results.
2. IE sents only one request to the server(I am using fiddler to see what requests are sent to server).
Can anybody guide me whats wrong with the code ? As far as I know XDR does not support synchronous calls, and asynchronous calls are giving me wrong results. Any workaround/tip for this problem.

Issue solved by myself when I pointed out a mistake in my code:(.
xdr = new XDomainRequest();
should be
var xdr = new XDomainRequest();
For Point 2 , I added "Cache-Control:no-cache" header in my response and it solved the matter.

Related

Primefaces: Default oncomplete method for all ajax request

I am trying to configure an oncomplete method for all ajax requests so that I can handle session timeout.
I tried adding the following script but it didn't work the same way as setting oncomplete property for p:ajax element. It wouldn't execute each time an Ajax request is made.
$.ajaxSetup({method: post,
complete: function(xhr, status, args){
var xdoc = xhr.responseXML;
if(xdoc == null){
return;
}
errorNodes = xdoc.getElementsByTagName('error-name');
if (errorNodes.length == 0) {
return;
}
errorName = errorNodes[0].childNodes[0].nodeValue;
errorValueNode = xmlDoc.getElementsByTagName('error-message');
errorValue = errorValueNode[0].childNodes[0].nodeValue;
alert(errorValue);
document.location.href='${pageContext.request.contextPath}/login/login.jsf';
}
});
Any help would be appreciated
PrimeFaces newer versions (using PF 5 here)
var originalPrimeFacesAjaxUtilsSend = PrimeFaces.ajax.Request.send;
PrimeFaces.ajax.Request.send = function(cfg) {
if (!cfg.oncomplete) {
cfg.oncomplete = doYourStuff;
}
originalPrimeFacesAjaxUtilsSend.apply(this, arguments);
};
Just to keep it somewhere, tried to find at stackoverflow but only older versions..
hope someone find this useful.
I managed to implement this by wrapping Primefaces AjaxUtils method.
var originalPrimeFacesAjaxUtilsSend = PrimeFaces.ajax.AjaxUtils.send;
PrimeFaces.ajax.AjaxUtils.send = function(cfg) {
if (!cfg.oncomplete) {
// register default handler
cfg.oncomplete = oncompleteDefaultHandler;
}
originalPrimeFacesAjaxUtilsSend.apply(this, arguments);
};
In primefaces there is component ajaxStatus which you can use for this purpose. Read documentation to see some more details about it, but for your use-case it can be something like this:
<p:ajaxStatus oncomplete="ajaxStatusHandler(xhr, status, args)"/>
and you can use your JavaScript function as is:
function ajaxStatusHandler(xhr, status, args) {
// your code ...
}
NOTE: this method can be used just for global AJAX requests (which is default in PrimeFaces), also, as I know, cross-domain script or JSONP (JSON with padding) requests can't be global.

AJAX Newbie , POSTing data on server

I started learning AJAX recently and am trying a very simple project which involves capturing some form data and sending it to two servers.
The first server is the one which hosts the website and server side php handling. This worls fine
The second server is a python basic http server which handles only the POST operation request send from AJAX. This functionality works but is a bit weird.
Let me explain
Here is my AJAX code which is absolutely straight forward.
function xml_http_post(url, data) {
var req = false;
try {
// Firefox, Opera 8.0+, Safari
req = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("Your browser does not support AJAX!");
return false;
}
}
}
req.onreadystatechange = function() {
if (req.readyState == 4) {
// callback(req);
}
}
req.open("POST", url, true);
req.setRequestHeader("Content-type","text/plain");
req.send(data);
}
Since I do not intend to send back any response , my callback function on ready state change is empty.
But when I execute this code ( triggered by onclick on a button) , the POST doesnt work and server doesnt seem to receive anything.
But the most surprising thing is that if I keep a breakpoint at req.open( ) and then do a manual step execution then it works always. Which means , I guess that there is some timing issue which needs to be resolved.
It works fine without breakpoints if the third parameter "async" is set to false but that is anyway undesirable so I want to make it work with async = true.
Any help would be greatly appreciated.
Thanks
Shyam
As I figured out, the form page was getting unloaded by a php script which was invoked as a action of the form b the first server. This resulted in the javascript code being partially or not executed.
So I figured out that sync XHR is the only way for my.

capture a pages xmlhttp requests with a userscript

I have a user script (for chrome and FF) that adds significant functionality to a page, but has recently been broken because the developers added some AJAX to the page. I would like to modify the script to listen to the pages xmlhttp requests, so that I can update my added content dynamically, based on the JSON formatted responseText that the page is receiving.
A search has turned up many functions that SHOULD work, and do work when run in the console. However they do nothing from the context of a user script.
(function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.addEventListener("readystatechange", function() {
console.log(this.readyState);
}, false);
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
From: How can I intercept XMLHttpRequests from a Greasemonkey script?
This works perfectly in the console, I can change this.readyState to this.responseText and it works great (though in the script I will need it to turn the JSON data into an object, and then let me manipulate it within the userscript. Not just write to the console). However if I paste it into a userscript nothing happens. The xmlhttp requests on the page do not seem to be detected by the event handler in the userscript.
The page doing the requesting is using the jquery $.get() function, if that could have anything to do with it. Though I don't think it does.
I can't imagine that there isn't a way, seems like any userscript running on an AJAX page would want this ability.
Since the page uses $.get(), it's even easier to intercept requests. Use ajaxSuccess().
This will work in a Greasemonkey(Firefox) script:
Snippet 1:
unsafeWindow.$('body').ajaxSuccess (
function (event, requestData)
{
console.log (requestData.responseText);
}
);
Assuming the page uses jQuery in the normal way ($ is defined, etc.).
This should work in a Chrome userscript (as well as Greasemonkey):
Snippet 2:
function interceptAjax () {
$('body').ajaxSuccess (
function (event, requestData)
{
console.log (requestData.responseText);
}
);
}
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
addJS_Node (null, null, interceptAjax);
Re:
"But how then do I get that data to the script? ... (So I can) use the data later in the script."
This works in Greasemonkey(Firefox); it might also work in Chrome's Tampermonkey:
Snippet 3:
function myAjaxHandler (requestData) {
console.log ('myAjaxHandler: ', requestData.responseText);
}
unsafeWindow.$('body').ajaxSuccess (
function (event, requestData) {
myAjaxHandler (requestData);
}
);
But, if it doesn't then you cannot share JS information (easily) between a Chrome userscript and the target page -- by design.
Typically what you do is inject your entire userscript, so that everything runs in the page scope. Like so:
Snippet 4:
function scriptWrapper () {
//--- Intercept Ajax
$('body').ajaxSuccess (
function (event, requestData) {
doStuffWithAjax (requestData);
}
);
function doStuffWithAjax (requestData) {
console.log ('doStuffWithAjax: ', requestData.responseText);
}
//--- DO YOUR OTHER STUFF HERE.
console.log ('Doing stuff outside Ajax.');
}
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
addJS_Node (null, null, scriptWrapper);

Problem with Ajax submission?

I am using Ajax to post data to the server(PHP code) and update it. i am posting many data one after the other, but in between the Ajax post fails and dont return a readyState to 4.
the code is as follows
function getHttpRequest()
{
var request=false;
if(window.XMLHttpRequest)
{
request=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
try
{
request=new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
request=new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
request=false;
}
}
}
return request;
}
the code begins here..
function updateAnswer(){
var request=getHttpRequest();
request.open('post','addAnswer.php');
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.send("answer="+ans);
if(request.readyState == 4)
{
var response=request.responseText;
document.getElementById("display").innerHTML=response;
}
}
i call this function to update answer in database but it donot return status=4 sometimes... please help
innerinnerHTML should be innerHTML. updateAnswer gets called each time readyState is changing from zero to four. Four is fully loaded, while those lesser are different loading stages.
Why not make life easier and use a framework like jQuery?
Also, can't you post all the data at once, in that way save a few roundtrips to the server?

Same Ajax is not working in IE more than one time

i my webpage when the user click forgot password button i ask email , Securitykey etc.. when the user click the sendmail button i send the email,securitykey, etc to a ajax function named 'sendmail(par1,par2,par3)' [Code is below]. The user provide Existing mailid , securitykey... , rtstr[1] is set to 1 [one] . So the 'Mail send successfully' was displayed . But if the user again enter the info [without refreshing the page]and click sendmail button, it didn't work in IE. But it works perfectly in Firefox.
var xmlhttp1;
xmlhttp1 = GetXmlHttpObject();
function sendmail(Mailforpwd, Secquestion, Secanswer) {
if (xmlhttp1 == null) {
alert("Browser does not support HTTP Request");
return;
}
var url = "SendEmail.php";
url = url + "?Email=" + Mailforpwd;
url = url + "&Squestion=" + Secquestion;
url = url + "&Sanswer=" + Secanswer;
xmlhttp1.onreadystatechange = stateChanged;
xmlhttp1.open("GET", url, true);
xmlhttp1.send(null);
function stateChanged() {
if (xmlhttp1.readyState == 4) {
var Result = xmlhttp1.responseText;
rtstr = Result.split('#');
//alert(xmlhttp1.responseText);
//alert(rtstr[0]);
//alert(rtstr[0]);
if (rtstr[0] == 1) {
document.getElementById("Errorcredentials").innerHTML = "Mail send successfully";
}
else if (rtstr[1] == 0) {
//alert(document.getElementById("Errorcredentials").innerHTML);
document.getElementById("Errorcredentials").innerHTML = "Please provide Exist information";
}
else {
document.getElementById("Errorcredentials").innerHTML = "There is a problem in sending mail, please try after sometime";
}
}
}
}
function GetXmlHttpObject() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject) {
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
Here my problem is at second time the function stateChanged() was not called , if i put a alert in this function , first time it display alert box , But next time it won't. This is my problem . The sendMail.php was called eachtime .
Whenever I have this problem it is because IE caches your AJAX request. The best way to avoid this is to append a random number as a key in your query string each time.
url = url + "&rand=" + Math.random();
Or, better, since your AJAX request appears to be causing some action to happen server-side, why don't you use HTTP POST instead of GET?
xmlhttp1.open("POST", url, true);
This is a caching problem. Append current date time to your url to make it unique.
url = url + "&rand=" + (new Date());
just swap these lines in your code.
xmlhttp1.onreadystatechange = stateChanged;
xmlhttp1.open("GET", url, true);
after fixing it looks like
xmlhttp1.open("GET", url, true);
xmlhttp1.onreadystatechange = stateChanged;
thats it!!
skypeid: satnam.khanna

Resources