img requests before windows close - javascript

I have the situation that data needs to be reliably sent before browser window closes. My current implementation is to use a synchronous AJAX calls. However that's unlikely to work in the near future because the browsers are deprecating synchronous XHR calls according to https://xhr.spec.whatwg.org/#synchronous-flag
What I'm trying is to replace the ajax call with a fake "img" call, parameterize data to be sent and append it as the image's url query string. It seemed to work so far I tried. I don't really care about the server response so that as long as the request is made and pushed to the wire before browser window is unloaded.
My question is how reliable it is? Has anyone gotten any expeirences?
My other options is to keep the data in a cookie or webstorage and send them on the next request but that's based on the assumption that user will revisit which may not be true in my case.
Thanks.

You can do it in unload event of window using ajax
you can refer the following links to know more about the problems and functionalities you need to take care of at this time in following links
Is there any possibility sending request before window closes
Is it reliable?
Is $(window).unload wait for AJAX call to finish before leaving a webpage
Hope this helps

I think better use ajax request. I have no proof, but from my expirience, dom work slowly then js. For an example, when you do this one:
var div = document.createElement('div');
div.innerHTML = "mama";
div.className = "myDiv";
document.getElementById("myWrapper").appendChild(div);
var text = document.getElementByClassName('myDiv')[0].innerHTML;
sometimes you will get exception with message - can't read property innerHTML of undefined.
But, if you will do that
setTimeout(function(){
var text = document.getElementByClassName('myDiv')[0].innerHTML;
}, 50);
it work allways fine. It's because dom still not updated. So, when you add image, dom may not be able to process it. And, when you send ajax request, it will be sended in any case I think.

Related

Simple way to include browser dimensions in request (Flask)

I would like to have the user's browser dimensions come through on each request. I tried having a global javascript snippet that would put it in the cookie, but that seemed to only work every other request for some reason.
It looks like this is setting the cookie after a page has loaded, in effect getting the cookie ready for the next request. This would kind of work, but as I mentioned it only works every other time.
jQuery(document).ready(function() {
var browser_width = jQuery(window).width();
document.cookie = 'width=' + browser_width;
console.log()
});
Is there a way to reliably provide the server (Flask, uwsgi) the dimensions on each request? I understand how getting dimensions the very first time the user visits the domain may be tricky, but you guys are smarter than I am.
(from the second request on would probably be ok if that's the reality)

How to implement window load callback when content has Content Disposition attachment?

I'm having a hard time figuring out the solution to a problem that I thought would be very common or straight-forward to solve, but apparently I was wrong.
I have to re-write some web code (that I didn't write) that's causing a problem. When a user clicks a link, a request is sent to the web server, which in turn fetches or creates a PDF document from somewhere. The PDF data is returned with the Content-Disposition header set to attachment, and the browser shows the save-as dialog.
The reason the save-as dialog appears is because when the user clicks the link, the Javascript sets window.location.href to the server URL (with some parameters).
There's no loading animation other than the one the browser shows in the tab etc. while the request is being processed.
The problem is that if a request hangs or takes a while, users tend to click the link again (possibly multiple times) which means requests for that same resource just keep building up on the server (even accidental double clicks on a link, which are common, cause two requests to be processed).
How can I prevent this from happening? If I do something like this (with window.location.href replaced by window.open:
var REQUEST_PENDING = false;
function getPDF(param1, param2) {
if (REQUEST_PENDING) return;
REQUEST_PENDING = true;
var w = window.open("/GetPdf.servlet?param1="+param1+"&param2="+param2);
w.onload = function() {
DOC_REQUEST_PENDING = false;
}
}
...then only one request will be processed at any one time, but the onload callback only works if the return content is HTML. When it's an attachment, which is what I have, the DOC_REQUEST_PENDING variable is never set back to false, so no further requests can be made.
I know that the ultimate solution should probably be implemented server-side, but is it not possible to achieve what I'm trying to do client-side? (I can use jQuery).
The question linked to in the comments above by #Cory does seem to be a duplicate of my question, and while I'm sure the accepted answer is perfectly fine, there is a bit involved in it. There's another answer for that question down the list somewhat that provides a link to this jquery plugin:
http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
...and for me anyway, this is the ultimate solution. Easy to use and works great.

can't change location of webpage using "window.onbeforeunload"

Can anybody pls tell me, how can i make a AJAX request and send user to some other page when he performs following actions ?
Clicks on next, prev btns of browser.
refresh page by any way(f5,ctrl+r,refresh btn).
try to close browser's window(Here i don't want to redirect him, just AJAX request).
i thought window.onbeforeunload could make it,
window.onbeforeunload = function () {
makeAjaxCall();
------
------
}
// Ajax Call is successful
function makeAjaxCall_SuccessHandler() {
window.location.href = 'Home.html';
}
but it is not working at all........
after searching on this topic i found that this is a kind of rule made for browser's security.
so pls tell me how to do this or any alternate way to achieve this.
You're not describing the actual behavior you're getting so I'm kinda guessing here, but I think your problem here is with the Asynchronous part of AJAX.
You see, when your onbeforeunload handler executes it may very well initiate the AJAX call BUT it won't block waiting for its results to return. Instead the execution will continue and onbeforeunload will complete before you ever get any result from your AJAX request (if any call is made at all).
First of all add some debug traces to validate your handler is actually executed. If it is, add an idle loop to keep it busy (preventing it from returning) and see if the AJAX call comes through (I'd check the server side for that).
If that's indeed the case I guess you'll have to modify the idle loop to consult some kind of flag. Or even better, if the libraries you use allow it, make the server call synchronous.
I think no.
Browsers can stop execution at any time after action. Ajax call is very long operation for this.
With onbeforeunload you can asking user questions like "Are use sure?". You must return string or assign it to event.returnValue
You can read about it here https://developer.mozilla.org/en/DOM/window.onbeforeunload
I think with your problem you can try to make synchroness call or try to open iframe with some GET parameter or send form data in iframe in body of this function. But i don't sure about time.

JQUERY or JS is there a way to detect anytime the Window is loading? Basically any network activity?

Is there a way with JQUERY or Javascript, to detect anytime the browser window is loading something, making an ajax call, loading an image, etc... Basically any network activity?
Something along the lines of this jQuery (put in the HEAD) should work.
var loading = true;
$(window).load(function () {
loading = false;
}).ajaxStart(function () {
loading = true;
}).ajaxComplete(function () {
loading = false;
});
Read up on ajaxStart for more details.
My answer below and the previous users' answers are only attempting to check if the browser is currently making an XmlHttpRequest (i.e. ajaxy) request.
You asked if you could tell if the browser was making any network request (i.e. downloading images/css or perhaps a long running 'comet' request). I don't know of any javascript API that would tell you this - they may exist but I suspect that if they do then they would be browser specific [if anyone out there knows the answer to this please chip in]. Obviously tools like Firebug and dynaTrace can detect network activity but I think these tool "hook in" to the browser a lot deeper down than javascript code.
Having said all that, if you want to count XHRs spawned by jQuery then dave1010's answer seems like a good one.
However I think it is prone to some race condition problems : -
According to the docs (http://api.jquery.com/ajaxStart/)
Whenever an Ajax request is about to be sent, jQuery checks whether there are any other outstanding Ajax requests. If none are in progress, jQuery triggers the ajaxStart event. Any and all handlers that have been registered with the .ajaxStart() method are executed at this time.
So if a long running XHR was started and another one was started before the first had completed, the ajaxStart handler would only be called once. The 2nd XHR could complete before the first one and set loading = false, even though the first request is still in progress.
Looking at the jQuery 1.4 source seems to confirm this. Interestingly, jQuery 1.4 has a count of active XHRs (jQuery.active) but this is not mentioned in the docs and so it is probably best not to use it (which is a pity because it would make life a bit easier).
See http://gist.github.com/277432#LID5052 for the code that checks to see that $.active is 0 before invoking ajaxStart handlers.
[I think] The 'ajaxSend' global event handlers are called before each and every XHR. Using this in preference to 'ajaxStart' should help but we will still need to keep a count of active requests as opposed to a simple "loading" flag.
Perhaps something like the following will work?
var activeXhrCount = 0;
$(document).ajaxSend(function() {activeXhrCount++;}).ajaxComplete(function(){activeXhrCount--;});
Be aware that this will give incorrect answers if any code calls $.ajax with the global option set to false and so is hardly bullet proof;
Also keep in mind that activeXhrCount only counts XHRs spawned by jQuery - those from other libraries that you may utilize will not be counted.
i think you have to build some think by your self,
i did something like this before [ like when gmail shows loading upper there ]
the idea is about making an array then add/remove from it and keep checking it for know if there is an open connection
the code should look like this
var liveAjax = [];
//making ajax call
liveAjax[liveAjax.length] = true;
$.ajax({
url: 'ajax/test.html',
success: function(data) {
liveAjax[liveAjax.length] = false;
or delete liveAjax[liveAjax.length]
}
});
then checking the alive calls by
setInterval(function(){
//looping in liveAjax and check if there any true value, then there is ajax call elese nothing happens
},200);

Firefox doesn't execute one dynamically loaded <script> element until another is loaded

I'm implementing Comet using the script tag long polling technique, based on this page. Following on from my previous question, I've got it all working, except for one annoyance, which only happens in Firefox.
On the initial page load my Comet client JavaScript sends two requests to the Comet server (in the form of dynamically generated <script> tags that are appended to the DOM):
get_messages - this is ongoing poll for messages from the application.
initialise - this is a once-off request at startup.
These two happen at the same time - that is, the <script> tags for both of them exist in the DOM at the same. (I can see them in the Firebug DOM inspector.) The server immediately sends some script as a response to the initialise request, but it doesn't send anything for the get_messages request until there's actually a message, which may take a while.
In Firefox 3.5 the script returned in the <script> tag for the initialise request does not get executed until the other <script> tag (for get_messages) also loads! In Chrome 3 and IE 8 this works fine - the script is executed as soon as it's received.
Why does Firefox do this and how do I fix it? I suppose I could try to work around it on the server by sending a dummy "message" at the same time as the initialise response, but that's quite a hack. I'd like to understand and fix this properly, if possible.
Seems to me to be a question of load order. Firefox always ensures that requests queued up execute in the order in which they were requested. IE does NOT ensure this (not sure about Chrome).
Regardless, if you shouldn't be calling get_messages until after the initialize code, you would want to trigger that request in the callback from your initialize function anyway. You'd want to do this no matter what, because other browsers may be inconsistent as well. IE6 for sure doesn't work the same way as other browsers regarding load order - it won't continue loading the DOM until the long-poll request completes, so you'd be stuck waiting around for your long poll interval just to see the main DOM load.
You can check out the source for our javascript client if you want details, we ran into similar issues when building our ASP.NET comet server, WebSync. The source can be viewed here:
http://sync.frozenmountain.com/client.ashx?debug=true
Do a search for "ie6" to see some of the workarounds.
I'm not sure why this is occurring, but perhaps a simple workaround would be to only add the get_messages <script> tag once the initialise request has completed. (I presume you have some callback that processes the response from the initialise request.)

Categories

Resources