Does Ajax block the window while processing the request? - javascript

I am making an ajax request where it may take much time to process the server-end.So I want to show a loading image at the time of request process.But loading image is not being shown while ajax requst.
var ref = createAjaxRequest();//Ajax req is created here...
if(ref){
showLoadingImg();
ref.open('POST','x.jsp',false);
ref.onreadystatechange = eventStateChange;
ref.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ref.setRequestHeader("Connection", "keep-alive");
ref.send();
}
else{ alert("Your browser does not support this feature");
}
function eventStateChange(){
if(ref.readyState==4 ){
//processing response here......
hideLoadingImg();
}
}
function showLoadingImg();{
/* <div id="ajaxLoading">(with background image is in page)
It is displayed properly when I set display:inline
manually through developer tools of a browser.</div>
*/
document.getElementById('ajaxLoading').style.display='inline';
}
function hideLoadingImg();{
document.getElementById('ajaxLoading').style.display='none';
}
is there anything wrong?
I tried to debug and found that:
Though showLoadingImg() is called before open() method, the loading image is displayed on browser only after ref.readyState==2.
But unfortunately time gap between readyState==2 and readyState==4 is very less, the loading image is immediately hidden.
Thus user cannot see the loading image...
So, what I am doubting is, doesn't ajax run the script unless it goes to readyState==2.

XMLHttpRequest blocks if you set async to false as you do with the third argument here: ref.open('POST','x.jsp',false);.

I thinks your call to open is wrong.
The third argument (boolean) indicates if the request is asynchronous or not.
Consider complete documentation here : http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
ref.open('POST','x.jsp',true);
Should solve your problem.
Regards

Related

Determining the HTTP status code of the initial request in javascript [duplicate]

Is there any way to get the http status of the current web page from javascript?
Spent some time searching on the web, but no luck at all... Seems like it's not possible, but wanted to check with Stack Overflow for maybe some fancy workaround.
(Providing it from the server as part of the response body is not acceptable, the status is supposed to be only available via the http header)
This is not in any way possible, sorry.
Yes You can
Simply request the same page, i.e. URI, using the XMLHttpRequest. Suppose that your page on /stop.php in stop.php you may do something like:
<script>
function xhrRequest(){
console.log(this.status);
// Do some logic here.
}
function getReq(url){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", xhrRequest);
oReq.open("GET", url);
oReq.send();
}
getReq("/stop.php");
</script>
Checkout this DEMO
🕯 Note:
You have to note that, it is a copy of the page not the page itself.
I, already, have used this solution on a page in which the server may
generate Forbidden HTTP status code when the request is come from
unauthorized IP address, so the condition here is very simple and
there is no much difference between the original and the copy page
that you have simulate its visit.
As a one liner:
fetch(location.href).then(response => console.log(response.status));
This is asynchronous, if you need a synchronous solution use XMLHttpRequest (as in the other answer) together with async: false or use async/await which feels synchronous, but is still asynchronous under the hood.
Alternatively
An approach without an extra call would need to include the status code in the page on the server side (e.g. in a meta tag), then read it on the client side via JavaScript.
Java + Thymeleaf:
<meta name="statuscode" th:content="${#response.status}">
PHP (unverified):
<meta name="statuscode" content="<?php echo http_response_code() ?>">
It is not beautiful, but you can use:
t = jQuery.get(location.href)
.success(function () { console.log(t.status) })
.error(function() { console.log(t.status) });
That When Eric says, this solution will make a new request from the same paga, and not show status of current request.
you can only check status of page loading
try:var x = document.readyState;
The result of x could be:
One of five values:
uninitialized - Has not started loading yet
loading - Is loading
loaded - Has been loaded
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded

Chrome Extension Background Page and Content Script Synchronization

Suppose I have the following code in my background page of a Chrome extension.
var opts;
chrome.storage.local.get(options, function(result) {
opts = result[options];
});
chrome.runtime.onMessage.addListener(function(request, sender, response) {
if (request.message === 'getOpts')
response(opts);
});
In my content script, I access opts with message passing.
chrome.runtime.sendMessage({'message': 'getOpts'}, function(response) {
console.log(opts);
});
Is there any guarantee that opts will be defined prior to a content script running? For example, when starting up the browser, the background page will run, and presumably the callback to chrome.storage.local.get will be added to the background page's message queue. Will Chrome finish processing that queue before injecting content scripts?
I could call chrome.storage.local.get from the content script, but my question is more generic, as I have additional async processing in my background page. At the moment, my content script checks with the background page to make sure everything is ready (using an interval to keep checking), but I am not sure whether such checks are necessary.
You can actually answer asynchronously to a message.
chrome.runtime.onMessage.addListener(function(request, sender, response) {
if (request.message === 'getOpts') {
chrome.storage.local.get('options', function(result) {
response(result[options]);
});
return true; // Indicate that response() will be called asynchronously
}
});
In case of chrome.storage this is, indeed, stupid as the API was specifically designed to addess the roundabout nature of using localStorage + Messaging in content scripts; you can query from content scripts directly.
But in general case of async processing, you can postpone answering to the message. You just need to return a true value from the listener to indicate that you're not done yet.
Do not rely on your variable being defined even if it is in your tests. In general, due to normal timing, your var should be set by the time it receives the message, but to be sure you should check so in your background onMessage. I've dealt with this by remembering in a global whether I've already initialized the extension and do so if needed from onMessage. The answer by xan shows how to use "return true" in that case to process the message once your async init finishes.
See an example of this on my chrome extension (search for bCalled)
There you can see I have a sendResponse method that takes care of detecting if the callback was already called and if not, return true (assumes an async operation is in progress and will call the callback later)
You can also experiment and test this by faking a delay in the background code that loads that var.

Is there a way to stop additional Javascript from running after a window.history.forward?

I have a JQuery file that gets loaded when the page is loaded. The very first line is:
window.history.forward(1);
Later in the file, there are Ajax calls that I'd like to disable if the forward command is going to prevent the page from loading (preventing a back button load).
The Ajax calls actually fail in this situation (Chrome reports the error, IE and Firefox don't but they do make the callback). Is there a way that I can get the status of the "forward" call and use it to gate the other calls?
One way you could detect whether the forward call did anything is to just check the URL before/after.
In other words, you could do something like:
var currentUrl = window.location;
window.setTimeout(function(){
if (window.location != currentUrl) return;
// The rest of your code that you want to go off if the forward didn't work
}, 1000 *2); // wait 2 seconds

Any way to gracefully enforce a timeout limit when loading a slow external file via javascript?

I'm using javascript to include some content served up from a php file on another server. However, this other service can sometimes get flaky and either take a long time to load or will not load at all.
Is there a way in JS to try to get the external data for x number of seconds before failing and displaying a "please try again" message?
<script type="text/javascript" src="htp://otherserver.com/myscript.php"></script>
Couple issues: you can use timeout thresholds with XMLHttpRequest (aka ajax), but then since it's on an otherserver.com you cannot use XMLHttpRequest (and support all A-grade browsers) due to the Same Origin Policy restriction.
If the script introduces any kind of global name (eg any variable name, function name, etc) You can try setTimeout to keep checking for it:
var TIMELIMIT = 5; // seconds until timeout
var start = new Date;
setTimeout(function() {
// check for something introduced by your external script.
// A variable, namespace or function name here is adequate:
var scriptIncluded = 'otherServerVariable' in window;
if(!scriptIncluded) {
if ((new Date - start) / 1000 >= TIMELIMIT) {
// timed out
alert("Please try again")
}
else {
// keep waiting...
setTimeout(arguments.callee, 100)
}
}
}, 100)
The problem as I see it is you cannot cancel the request for the script. Please someone correct me if I'm wrong but removing the <script> from the DOM will still leave the browser's request for the resource active. So although you can detect that the script is taking longer than x seconds to load, you can't cancel the request.
I think you may be out of luck.
The only way I can think of doing this is to create a proxy on another (PHP-enabled) server which will fetch the data for you, but will stop when a certain timeout limit has been reached (and it can just return an empty result).
This is purely, purely theoretical:
<script> tags can be dynamically inserted into the DOM, at which point the script will be fetched and processed. This dynamic script tag injection is how some achieve cross-domain "AJAX."
I would imagine you could declare a global variable var hasLoaded = false;. At the end of the script you are attempting to load you could set that variable to true hadLoaded=true;. After injecting the script tag into the DOM you could then kickoff a setTimeout() whose callback function checks to see if "hasLoaded" is set to true. If it isn't, you can assume the script has not yet loaded fully into the browser. If it has, you can assume it has loaded completely.
Again, this is theoretical, but if you test it be sure to report back, I'm very curious.
I think that the only way to do this is take the content of the file via ajax and then set a timer. If the request finishes before the timer you can evaluate the respons with eval(that's not the better solution anyway), otherwise you can stop the ajax request and write the error message.

Ajax call not responding on repeated request

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/

Categories

Resources