Clickonce after asynchrone call - javascript

When directly opening a clickonce application after a user event it works. When there is some asynchrone code it fails. I found this site describing the problem exactly, but not supplying a solution. Any idea? Changing the browser settings is not a option.
//Following works:
$('#buttonId').click(function() {
window.location.href = 'path/to/clickonce/app.application';
});
//Following fails:
$('#buttonId').click(function() {
$.ajax({
...
success: function () {
window.location.href = 'path/to/clickonce/app.application';
}
});
});

Related

Ajax method does not fire on initial page load

Note: Please see edit at the bottom after reading this question.
This issue is only happening in IE 11, and only started occurring after a recent Windows update. There were 5 updates, one of which was specific to IE, so I uninstalled that one. However, the issue still exists. Before I consider rolling back the remaining updates, is there something inherently wrong in my code? The following is inside the document ready function:
$('#leftmenu>li').click(function () {
var clickedId = this.id;
$.ajax({
url: "Session/Index/",
cache: false,
success: function (result) {
if (result.length > 0)
{
performListItemAction(clickedId);
}
else
{
window.location.href = 'Home/Index/'
}
}
});
});
And the following is the performListItemAction method (a separate function not in document.ready):
function performListItemAction(item)
{
alert("clicked");
$(".tabui").each(function ()
{
$(this).hide();
});
$(".listitem").each(function ()
{
$(this).css("background", "transparent");
});
$(document.getElementById(item)).css("background-color", "#C8C8C8");
var targetId = $(document.getElementById(item)).data('target');
var target = $(document.getElementById(targetId));
target.show();
}
The alert clicked never appears when this problem happens, and that is how I concluded the ajax call is not working.
A few other notes:
This issue isn't happening on Firefox.
This only happens if I directly login to the page with a direct URL. If I log in via the application's home screen, and then go to the page that uses the above javascript, the issue doesn't occur.
Thank you.
EDIT: I just now see that the same issue is now occurring in Firefox as well. It's just much less frequent.
After trial and error, I think I fixed the issue by adding a forward slash to the beginning of each of the URLs, and added the type: "POST", to the ajax call. I don't know why it was working fine before, but now this works in all my attempts.

how to load google client.js dynamically

this is my first time to post here on stackoverflow.
My problem is simple (I think). I am tasked to allow users to sign up using either Facebook, Google Plus, LinkedIn and Twitter. Now, what I want to do is when the user clicks the Social Network button, it will redirect them to the registration page with a flag that determines which social network they want to use. No problem here.
I want to load each API dynamically depending on which social network they choose.
I have a problem when loading the Google JS API, dynamically. The sample found in here loads client.js in a straightforward manner. I have no problems if I follow the sample code. But I want to load it dynamically.
I tried using $.ajax, $.getScript and even tried adding the script to the page just like how you call Google Analytics asynchronously. None of the above worked. My call back function is NOT called all the time. Also, if i call the setApiKey from the call back function of $.ajax and $.getScript, the gapi.client is NULL. I don't know what to do next.
Codes that did not work:
(function () {
var gpjs = document.createElement('script'); gpjs.type = 'text/javascript'; gpjs.async = false;
gpjs.src = 'https://apis.google.com/js/client.js?onload=onClientLoadHandler';
var sgp = document.getElementsByTagName('script')[0]; sgp.parentNode.insertBefore(gpjs, sgp);})();
Using $.getScript
$.getScript("https://apis.google.com/js/client.js?onload=onClientLoadHandler", function () {
console.log("GP JS file loaded.");
SetKeyCheckAuthority();});
Using $.ajax
$(document).ready(function () {
$.ajax({
url: "https://apis.google.com/js/client.js?onload=onClientLoad",
dataType: "script",
success: function () {
console.log("GP load successful");
SetKeyCheckAuthority();
},
error: function () { console.log("GP load failed"); },
complete: function () { console.log("GP load complete"); }
});});
May I know what is the proper way of calling this js file dynamically? Any help would be appreciated. Thank you.
Ok, I just thought of a solution but i think it's a bad one. Please let me know what you think of it.
i used $.getScript to load the js file
$.getScript("https://apis.google.com/js/client.js?onload=onClientLoadHandler", function () {
console.log("GP JS file loaded.");
SetKeyCheckAuthority();});
and then on my SetKeyCheckAuthority function i placed a condition to call itself after 1 second when gapi.client is null.
function SetKeyCheckAuthority() {
if(null == gapi.client) {
window.setTimeout(SetKeyCheckAuthority,1000);
return;
}
//set API key and check for authorization here }

Two functions in onclick - Ajax call in second (cross browser)

I have
Click me
What I want to do is take the confirmation box result (true/false), pass it to the submit button, and then kill the href call if its false.
I have it working in my development environment, but when I load this into a cross browser scenario, the second call isn't working:
function submit(msg, evt) {
if(msg == true) {
$.ajax({
type:"POST",
data:{answer:'Correct'},
url:'https://myurl/p'
});
}
else { evt.preventDefault(); return false; }
}
The URL passed is just the URL and has no data to it (in production). This exact code works perfectly fine in my environment, but in the cross browser scenario it fails. If I remove the confirmation box, everything works perfectly.
I have a feeling it's tied to the preventDefault call on the cancel of the confirmation box. Would that preventDefault disable the next call out with that same link?
First of all, please don't use inline event handlers, you can remove this from the markup and deal with it in your js where it belongs:
HTML:
Click me
JS:
anchor = $('#myanchor')[0];
anchor.on('click',function(){
var msg = confirm('Confirm?');
submit(msg, event);
});
Secondly, if msg is true the ajax call is immediately interrupted by a page redirect, which doesn't make much sense. I believe you want the redirect to take place once the ajax call has completed, in which case you should use:
function submit(msg, evt) {
if(msg == true) {
$.ajax({
type:"POST",
data:{answer:'Correct'},
url:'https://myurl/p',
complete: function(){window.location="url";}
});
}
evt.preventDefault();
return false;
}
Click me
$(function(){
$("#myUrlID").click(function(event){
event.preventDefault();
var msg = confirm('Confirm?');
if(msg == true) {
$.ajax({
type:"POST",
data:{answer:'Correct'},
url:'https://myurl/p'
});
}
});
});

Javascript reload() not working

I searched everywhere here to see since so many people ask this question, but no matter what, I keep getting undefined..
function remove_item(itemid) {
var window = top.location;
var host = window.host;
$.ajax({
url: "http://"+host+"/backend/remove_lockbox.php?id="+itemid,
success: function() {
$(document).ajaxStop(function(){
window.top.location.reload();
});
}
});
}
That is my code. I tried window.location.reload, host.location.reload... I tried everything and I keep getting undefined... The parent of location is always undefined whether it's window, host, window.top, ANYTHING.
Can someone PLEASE help me?
So you are doing
var window = top.location;
and than you do
window.top.location.reload();
So you are actually saying
top.location.top.location.reload();
Why would you use a variable named window when that is already defined and has a different meaning? That is bad.
If you are using frames I would expect to see something like
parent.location.reload(true);
or just a plain old window
window.location.reload(true);
try it this way, its working fine in chrome, as I know this should work fine in all modern browsers.
function remove_item(itemid) {
var host = window.location.host;
$.ajax({
url: "http://"+host+"/backend/remove_lockbox.php?id="+itemid,
success: function() {
$(document).ajaxStop(function(){
window.location.reload();
});
}
});
}
Here is the working example of window.location, window.location.host and window.location.reload.
http://jsbin.com/apemen/3

window.onbeforeunload ajax request in Chrome

I have a web page that handles remote control of a machine through Ajax. When user navigate away from the page, I'd like to automatically disconnect from the machine. So here is the code:
window.onbeforeunload = function () {
bas_disconnect_only();
}
The disconnection function simply send a HTTP GET request to a PHP server side script, which does the actual work of disconnecting:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
});
}
This works fine in FireFox. But with Chrome, the ajax request is not sent at all. There is a unacceptable workaround: adding alert to the callback function:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
alert("You're been automatically disconnected.");
});
}
After adding the alert call, the request would be sent successfully. But as you can see, it's not really a work around at all.
Could somebody tell me if this is achievable with Chrome? What I'm doing looks completely legit to me.
Thanks,
This is relevant for newer versions of Chrome.
Like #Garry English said, sending an async request during page onunload will not work, as the browser will kill the thread before sending the request. Sending a sync request should work though.
This was right until version 29 of Chrome, but on Chrome V 30 it suddenly stopped working as stated here.
It appears that the only way of doing this today is by using the onbeforeunload event as suggested here.
BUT NOTE: other browsers will not let you send Ajax requests in the onbeforeunload event at all. so what you will have to do is perform the action in both unload and beforeunload, and check whether it had already taken place.
Something like this:
var _wasPageCleanedUp = false;
function pageCleanup()
{
if (!_wasPageCleanedUp)
{
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com/PageCleanup?id=123',
success: function ()
{
_wasPageCleanedUp = true;
}
});
}
}
$(window).on('beforeunload', function ()
{
//this will work only for Chrome
pageCleanup();
});
$(window).on("unload", function ()
{
//this will work for other browsers
pageCleanup();
});
I was having the same problem, where Chrome was not sending the AJAX request to the server in the window.unload event.
I was only able to get it to work if the request was synchronous. I was able to do this with Jquery and setting the async property to false:
$(window).unload(function () {
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com?id=123'
});
});
The above code is working for me in IE9, Chrome 19.0.1084.52 m, and Firefox 12.
Checkout the Navigator.sendBeacon() method that has been built for this purpose.
The MDN page says:
The navigator.sendBeacon() method can be used to asynchronously
transfer small HTTP data from the User Agent to a web server.
This method addresses the needs of analytics and diagnostics code that
typically attempt to send data to a web server prior to the unloading
of the document. Sending the data any sooner may result in a missed
opportunity to gather data. However, ensuring that the data has been
sent during the unloading of a document is something that has
traditionally been difficult for developers.
This is a relatively newer API and doesn't seems to be supported by IE yet.
Synchronous XMLHttpRequest has been deprecated (Synchronous and asynchronous requests). Therefore, jQuery.ajax()'s async: false option has also been deprecated.
It seems impossible (or very difficult) to use synchronous requests during beforeunload or unload
(Ajax Synchronous Request Failing in Chrome). So it is recommended to use sendBeacon and I definitely agree!
Simply:
window.addEventListener('beforeunload', function (event) { // or 'unload'
navigator.sendBeacon(URL, JSON.stringify({...}));
// more safely (optional...?)
var until = new Date().getTime() + 1000;
while (new Date().getTime() < until);
});
Try creating a variable (Boolean preferably) and making it change once you get a response from the Ajax call. And put the bas_disconnect_only() function inside a while loop.
I also had a problem like this once. I think this happens because Chrome doesn't wait for the Ajax call. I don't know how I fixed it and I haven't tried this code out so I don't know if it works. Here is an example of this:
var has_disconnected = false;
window.onbeforeunload = function () {
while (!has_disconnected) {
bas_disconnect_only();
// This doesn't have to be here but it doesn't hurt to add it:
return true;
}
}
And inside the bas_send_request() function (xmlhttp is the HTTP request):
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
has_disconnected = true;
}
Good luck and I hope this helps.
I had to track any cases when user leave page and send ajax request to backend.
var onLeavePage = function() {
$.ajax({
type: 'GET',
async: false,
data: {val1: 11, val2: 22},
url: backend_url
});
};
/**
* Track user action: click url on page; close browser tab; click back/forward buttons in browser
*/
var is_mobile_or_tablet_device = some_function_to_detect();
var event_name_leave_page = (is_mobile_or_tablet_device) ? 'pagehide' : 'beforeunload';
window.addEventListener(event_name_leave_page, onLeavePage);
/**
* Track user action when browser tab leave focus: click url on page with target="_blank"; user open new tab in browser; blur browser window etc.
*/
(/*#cc_on!#*/false) ? // check for Internet Explorer
document.onfocusout = onLeavePage :
window.onblur = onLeavePage;
Be aware that event "pagehide" fire in desktop browser, but it doesn't fire when user click back/forward buttons in browser (test in latest current version of Mozilla Firefox).
Try navigator.sendBeacon(...);
try {
// For Chrome, FF and Edge
navigator.sendBeacon(url, JSON.stringify(data));
}
catch (error)
{
console.log(error);
}
//For IE
var ua = window.navigator.userAgent;
var isIEBrowser = /MSIE|Trident/.test(ua);
if (isIEBrowser) {
$.ajax({
url: url,
type: 'Post',
.
.
.
});
}
I felt like there wasn't an answer yet that summarized all the important information, so I'm gonna give it a shot:
Using asynchronous AJAX requests is not an option because there is no guarantee that it will be sent successfully to the server. Browsers will typically ignore asynchronous requests to the server. It may, or may not, be sent. (Source)
As #ghchoi has pointed out, synchronous XMLHTTPRequests during page dismissal have been disallowed by Chrome (Deprecations and removals in Chrome 80). Chrome suggests using sendBeacon() instead.
According to Mozilla's documentation though, it is not reliable to use sendBeacon for unload or beforeunload events.
In the past, many websites have used the unload or beforeunload events to send analytics at the end of a session. However, this is extremely unreliable. In many situations, especially on mobile, the browser will not fire the unload, beforeunload, or pagehide events.
Check the documentation for further details: Avoid unload and beforeunload
Conclusion: Although Mozilla advises against using sendBeacon for this use case, I still consider this to be the best option currently available.
When I used sendBeacon for my requirements, I was struggling to access the data sent at the server side (PHP). I could solve this issue using FormData as recommended in this answer.
For the sake of completeness, here's my solution to the question:
window.addEventListener('beforeunload', function () {
bas_disconnect_only();
});
function bas_disconnect_only () {
const formData = new FormData();
formData.append(name, value);
navigator.sendBeacon('URL', formData);
}
I've been searching for a way in which leaving the page is detected with AJAX request. It worked like every time I use it, and check it with MySQL. This is the code (worked in Google Chrome):
$(window).on("beforeunload", function () {
$.ajax({
type: 'POST',
url: 'Cierre_unload.php',
success: function () {
}
})
})
To run code when a page is navigated away from, you should use the pagehide event over beforeunload. See the beforeunload usage notes on MDN.
On that event callback, you should use Navigator.sendBeacon(), as Sparky mentioned.
// use unload as backup polyfill for terminationEvent
const terminationEvent = "onpagehide" in self ? "pagehide" : "unload";
window.addEventListener(terminationEvent, (event) => {
navigator.sendBeacon("https://example.com/endpoint");
});

Categories

Resources