Ajax call not responding on repeated request - javascript

I have a page with a dropdown. The onchange event calls a Javascript function (below) that includes an Ajax block that retrieves data and populates a TEXTAREA. On the surface, everything works.
I can select any item in the list with no problems. However, if I select an item that has previously been selected, the Ajax call appears to hang. It looks like maybe some weird caching issue or something. If I close the browser and reload the page, all items work again until I re-select.
I've tested for the readyState and status properties when it's hanging, but I get nothing. Am I missing something?
The page is a client project behind authentication so I can't post a URL, but here's the Ajax code. This is in a PHP page, but there's no PHP script related to this.
function getText( id ) {
var txt = document.getElementById( "MyText" );
txt.disabled = "disabled";
txt.innerText = "";
txt.className = "busy";
var oRequest = zXmlHttp.createRequest();
oRequest.open( "get", "get_text.php?id=" + id, true );
oRequest.send( null );
oRequest.onreadystatechange = function() {
if( oRequest.readyState == 4 ) {
if( oRequest.status == 200 ) {
txt.innerText = oRequest.responseText;
} else {
txt.innerText = oRequest.status + ": " + oRequest.statusText;
}
txt.disabled = "";
txt.className = "";
oRequest = null;
}
}}
Edit: The code block seems a little quirky; it won't let me include the final } unless it's on the same line as the previous.

You're setting the onreadystatechange function after you're sending the request. If it takes a long time (ie if it goes to the server), this will probably work, since there will be a delay before it tries to call the callback.
If the page is cached, though, the browser is probably trying to call onreadystatechange immediately in the send method. Move your assignment to onreadystatechange to before the open/send code.

HI,
The caching is due to the same url thats being called repeatedly. If you change the URl dynamically then this issue can be rsolved. Something like by adding a querystring with the current time with the request ( or any random renerated number ) you can change the url without affecting the result

I would guess that you are running into a caching issue. I have noticed that Internet Explorer is more aggressive at caching ajax calls than Firefox is. One way to be sure of what is happening is to use Fiddler2. This application monitors your web traffic, and you would be able to see if the browser is making a request or not, and what cache headers are coming back on the responses that you do get.
You can download fiddler2 from http://www.fiddlertool.com/fiddler/

Related

Redirecting XMLHTTP request - Javascript

I have a web page that has a too much content and javascript. When the page loads it makes multiple requests using Ajax and XMLHttp to load data. Is there a way to hook up all these requests and direct them to a different server.
For example the webpage fetches data from www.apple.com/data and www.mango.com/data after it is loaded. Is is possible to insert a script somewhere in the webpage which automatically changes any request made to www.orange.com/data.
Waiting for answer. Thanks
You can add a global handler to the ajaxSend event, the event will be triggered right before the ajax request being sent out. So you can check the request uri, apply some filtering logic, and then redirect the request by abort the original and resend it.
Below is an example
$(document).ajaxSend(function(e, xhr, opt) {
if (opt.url.indexOf("www.apple.com") !== -1) {
// abort the request
xhr.abort();
// change the uri to www.orange.com
opt.url = opt.url.replace("www.apple.com", "www.orange.com");
$.ajax(opt);
}
});
Ok. So I followed Anthony C's answer and it did actually work. But the problem with his solution is that it only works with Ajax requests not XMLHttpRequests (I am not sure why, I am a beginner at this topic.) However digging on his idea of creating a hook I came across a similar post here How to get the URL of a xmlhttp request (AJAX). The code provided a way to fetch the requested URL for each request. So by a little tweak to the code I managed to come up with this:-
XMLHttpRequest.prototype.open = (function(open) {
return function(method,url,async) {
var uri=getLocation(url);// use get location function to convert requested url string into readable url
if(uri.hostname!="orange.com"){
url="https://orange.com" + url;
}
open.apply(this,arguments);
};
})(XMLHttpRequest.prototype.open);
var getLocation = function(href) {
var l = document.createElement("a");
l.href = href;
return l;
};
This code at top of the page allows me to change the host name of all XMLHttpRequests that are not directed towards orange.com. Though I am sure there are better ways to write this code as well but since I am not an expert over javascript this will suffice my need for the time.

Redirect via POST - Nothing happening in Firefox

I have an endpoint that expects a POST request and produces a file. On the front end I need to redirect the page using a form submittal. However, I need to generate the form dynamically (for a variety of reasons on the front end).
Here is my attempt (bear in mind, I had to edit the code a bunch since it sits across various http related components):
sendRedirect(options) {
options.form = this.createForm(options.body);
options.form.setAttribute('method', 'post');
options.form.setAttribute('action', redirectTo);
options.form.submit();
}
createForm(body) {
let form = window.document.createElement('form');
return Object.keys(body).reduce((_form, key) => {
let i = document.createElement('input');
i.setAttribute('type', 'hidden');
i.setAttribute('name', key);
i.setAttribute('value', body[key]);
_form.appendChild(i);
return _form;
}, form);
}
The above works fine in google chrome. However, in firefox, nothing happens (i.e. no network request is sent after the form.submit() executes). I have stepped through the code in firefox and it seems to be executing just fine (i.e. all the variables are set to what they are supposed to be). The code reaches its end of execution at form.submit() and then... nothing.
Thanks in advance.
Edit: Thanks to Quentin for the answer. Here is the code that I added to make it work:
options.form.style.visibility = 'hidden';
window.document.getElementsByTagName('body')[0].appendChild(options.form);
The form needs to be part of the document for Firefox to submit it.
Append it to (for example) document.body before calling submit.

Is ajax request slowing down the browser?

I try to send ajax requests and do GUI animation in the same time(about 150 requests in a second). It's fine when I doing the first time, and the animation becomes laggy even I refresh the page or restart the browser.
Therefore I tried removing everything in ajax callback, but the browser still acts very laggy while waiting responses. I also tried jquery $.get, and set async to 'true', but the problem still exists.
However, if I change ajax to websocket, this problem is solved. Is that means, ajax requests send by js affect performance? I want to figure this out, thanks!
code :
var i = 0;
var f = setInterval(function(){
// url is an array
addItem(url[i]);
i++;
if(i >=url.length) clearInterval(f);
},33);
// send ajax requests
function addItem(url){
var xml = new XMLHttpRequest();
xml.open('GET',url,true);
xml.send();
xml.onreadystatechange = function(){
if(xml.readyState == 4 && xml.status==200){
// do nothing
}
}
}
150 requests/second seems like bad design. You need to group your requests and send fewer. The animation makes it worse. I believe there is no valid explanation to have this many requests. Yes, you can switch to WebSocket, but make sure your communication does not duplicate messages and does not send multiple messages which could be sent as a single message.

passing data from authentication cookie to javascript

I am using an authentication cookie passed between websites on the same domain. The cookie contains some user info and page info (the accession number). The design goal is for the user to click a button on the referring website, and it will launch a second website, authenticate based on the cookie, and do some useful stuff with the accession number. I got most of this built, including getting the authentication passed and properly parsed out on the receiving system.
The problem I am having is that I can't get the data within the cookie into the javascript on the page. It seems when i launch website2 from website1, $(document).ready() is not fired after the page_load event (which handles the cookie parsing). Also I tried using a literal to post the javascript code, it's never fired (seemingly it places it after the client side stuff is executed.
What I really want to do is call a javascript function getResults(accnum) using this data.
I have this code on the page_load event:
if (userdata != null)
{
accnum = userdata[4];
}
if (accnum != String.Empty)
{
//HttpCookie accnumcookie = new HttpCookie("accnum", accnum);
//this.Context.Response.Cookies.Set(accnumcookie);
}
}
When I run the .Set function, I'm not really sure of the innards and details, but long story short, the cookie is set but does nothing.
This is the document.ready.
$(document).ready(function () {
var accnum = new String();
accnum = GetCookie('accnum');
if (accnum != null) {
document.cookie = 'test=testz';
var srch = document.getElementById('crit');
srch.style.display = 'none';
getResults('', 'accnum', accnum);
}

getElementById() null error

For those who wants the soluce before the question :
1 ) Don't read an element with getElementById() before it's really created : see windows.onload.
2 ) If you are using XMLHTTPRequest and AJAX stuff, call you're getElementById() , or unlock this function, in the callback ,(xhr_object.readyState == 4 part of your request).
In my case, i call my page without using the desired callback (noobish Ctrl-C Ctrl-V style).
Here was the question :
I'm facing a strange case in a HTML/Javascript code.
The aim of this code is to get the value of an HTML input (type text) via a JS function.
The context is that a main HTML page loads my all my JS functions, and loads on demand HTML contents in sub divs via HTTPRequest.
The selected code is called after the divs has been loaded.
Here's the PHP generated Input field that i have to read:
<input id="listejf" type="text" value="6|7|">
Here's my JavaScript call :
listejf=document.getElementById('listejf').value;
alert(listejf);
This code doesn't work. Firebug sends me:
TypeError: document.getElementById("listejf") is null
The strange thing is that I can make it work if I call the getElementById through an alert like this:
alert(document.getElementById("listejf"));
listejf=document.getElementById('listejf').value;
alert(listejf);
The first alert displays null, but the second one "6|7|", as expected.
Now, 2 questions:
Why does alert make it work ?
How can I make it work without throwing alerts everywhere?
Re-edit, the code was gone :
That's is the main HTML page : main.html
<head>
<script type="application/javascript" src="./preload.js"></script>
</head>
<body>
Link
<div id="targetid"></div>
</body>
preload.js looks like that :
function CallPagen() {
envoieRequete('./PageN.php', 'targetid');
}
function mytestfunction() {
listejf = document.getElementById('listejf').value;
alert(listejf);
}
function envoieRequete(url, id) {
var xhr_object = null;
if (window.XMLHttpRequest) xhr_object = new XMLHttpRequest();
else if (window.ActiveXObject) xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
xhr_object.open("GET", url, true);
xhr_object.onreadystatechange = function () {
if (xhr_object.readyState == 4) {
if (!document.getElementById(id)) {
alert("id pas trouvé " + id);
}
document.getElementById(id).innerHTML = xhr_object.responseText;
mytestfunction();
}
};
xhr_object.send(null);
}
PageN.php just echoes the inputtext field with the value filled.
"...I can make it work if i call the getelement through an alert like this..."
This almost always means that you're making an asynchronous AJAX request.
"Why does alert make it work ?"
What happens is that the alert delays the processing of the next line of code long enough for the response to return.
Without the alert, the next line of code runs immediately, and the element is not yet available.
"How can I make it work without throwing alerts everywhere?"
This is a very common issue. The solution is that you need to put any code that relies on the response of the XMLHttpRequest request inside a callback to the request.
So if you're making a request through the native API, you'd add a onreadystatechange callback...
xhrRequest.onreadystatechange = function() {
if (xhrRequest.readyState === 4) {
// append the response text to the DOM
listejf=document.getElementById('listejf').value;
alert(listejf);
}
}
You should run the code after DOM is ready, when the alert() is called, document is loading and browser has time for creating the DOM objects, try the following:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.
window.onload = function() {
var listejf = document.getElementById('listejf').value;
alert(listejf);
};

Categories

Resources