I can't find a way to execute a script when a page is reached via the browser's BACK button or key command. (Background: I need to know if a page was opened using the browser's BACK button or key command. Then I could check for a stored sessionStorage varible and trigger some appropriate stuff).
If, for example, I put this into my page code
<script>
$(document).ready(function() {
alert("YES!");
/* in the real situation: do something */
})
</script>
, the alert will be displayed when I load the page via a link or by opening it directly by typing its URL into the address bar.
But this alert will not appear when I come to that page via the BACK button.
I tried the same using $(window).on("load", function() {... and $(window).on("navigate", function () {... - no success either...
EDIT / ADDITION:
I just realized that browsers behave differently in this respect: Chrome, Opera, IE and Firefox Windows will reload the page correctly (and trigger document.ready() and onload() events) , but Firefox Mac and Safari will not - they load the whole page from cache without triggering document.ready() or onload(). (I haven't tried mobile browsers yet)
So i searched for solutions avoiding the cached content, but what I've found and tried so far (which is a lot!) hasn't worked either...
after reading lots of posts and trying the solutions in there and narrowing the thing down to a browser issue, I discovered this answer, which forces the page to be reloaded also in Safari (and apparently also Firefox/Mac):
https://stackoverflow.com/a/13123626/5641669
Essentially, this jQuery code reloads the page in its original state when coming there via the back button on Safari, which also allows to trigger any desired script on pageload:
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
Related
Does anyone know a way, via JavaScript, that I can either clear Safari's bfcache, or force it to reload rather that used a cached version of a page?
I have a web application that is running tests, and there is JavaScript which monitors a countdown (a timeout):
timeoutId = window.setInterval(function () {
timeoutRemaining--;
if (timeoutRemaining <= 0) {
location.href = myTimeoutLocation;
}
}, timeoutInterval);
This all works fine until I get to myTimeoutLocation. The behavior is that, if a user clicks the back button, the test should continue. However, when navigating back, I find that IE and Chrome reload the page, but Firefox and Safari are showing the cached page. I need to make sure that a cached page is NEVER shown. I can fix this problem in Firefox by adding:
window.onunload = function () { };
to my script, but that hasn't worked in Safari since Safari 5.x (as far as I can tell). I found another solution:
window.addEventListener("pageshow", function(evt){
if(evt.persisted){
setTimeout(function(){
window.location.reload();
},10);
}
}, false);
This worked to an extent... The problem I have now is that even with the above code, I am receiving a dialog box: ... which I'm apparently not allowed to embed. The dialog says that in order to display the page, information must be sent to the server, with the appropriate confirm or deny buttons. I did try setting forceGet to true, but that did not solve the problem with the dialog appearing. I should mention that clicking Resend has the desired effect.
Non-embedded image of dialog
And yes, I realize the image is of Firefox, not Safari.
In case it makes any difference (even though this is a JavaScript question), the site is coded in .NET/MVC4 and is hosted in IIS.
Thank you in advance for any help/thoughts/information/pointers in the right direction.
I have been tasked with emulating a JavaScript alert without using a JavaScript alert. I also cannot use jQuery in this app. So far, I have JavaScript that opens a new window using window.open. When the user blurs away from the popup window I'm creating and then some new data loads in it, I need the window to focus again for the user. This works fine in IE, Chrome, and Firefox on this static HTML page; however, when I try the same thing from our ASP.NET application, it only works in IE. The window updates as expected, but it never refocuses for the user in other browsers.
Here's the code I use to re-focus the window:
window.onload = function() {
window.focus();
};
To open the window initially from the ASP.NET app, I'm using:
ClientScriptManager.RegisterClientScriptBlock(GetType(), "OurWindow", "OpenTheWindow();", true)
I've tried lots of what's already out there (such as these) to no avail. Am I missing something?
Edit: I added a little location.reload(); to the first page to simulate a postback from ASP.NET, but that didn't change anything.
I have seen related questions on StackOverflow, but none of the suggestions are working for me. I need browsers to reload a page from the server every time it is displayed, including if the user got there by pressing the Back button. It seems like browsers obey caching rules for everything except the base document. This happens in current versions of Safari and Firefox (as of Dec 2013), verified by packet capture.
The pages in my application are used to edit a database record. At the top of the source files are a couple lines of PHP to store a lock indicating that the record is being edited. Other users cannot edit the same record while the lock exists. The pages have a window unload handler that uses AJAX in non-async mode to release the lock. (There's more to the locking mechanism, but those are the relevant pieces.) When the user returns to the page via Back button, the server-side code is never executed.
I have tried including a header:
Cache-Control: no-cache, must-revalidate
Safari's inspector shows the header was received and processed, but it still does not re-retrieve the page.
I have tried setting a handler to check whether the page's state was maintained:
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload();
}
};
The if condition never matches: event.persisted is always false.
The annoying part is that this appears to be technically correct. According to the relevant part of the HTML5 spec, since the page registers an unload listener the browser should never try to maintain page state. And it doesn't! When the user presses the back button, the browser is "replaying" the entire page load sequence, including the ready event. It repeats any AJAX calls where the prior results were not cached. The only thing it refuses to actually reload from the server is the main document itself.
How do I get it to reload the main document?
Quick answer:
No you can't... the Back button is even more aggressive and different of a cache than the others. Some insight:
Why is Google Chrome going to the server on pushState?
https://github.com/nickhsharp/prefetchNightmare
That said... a GET request (the browser loading it) shouldn't "do" anything to the server... if anything you should do that lock setting part via an AJAX on the page start... the inverse of how you remove it using AJAX on the done part.
The browsers are pretty clear on their reasons for the crazy BACK/FORWARD caches and you're not going to be able to force their hands on this one.
Adding this code to my HTML works just fine for me:
<input id="isOld" type="hidden" />
<script>
onload = function () {
var el = document.getElementById('isOld');
if (el.value) {
el.value = '';
location.reload();
}
el.value = true;
};
</script>
The code assigns a value to the hidden input that will remain after the back button is clicked in which case the page is force refreshed.
And here's a stripped down version of the above:
<input id="isOld" type="hidden" />
<script>
setTimeout(function () {
var el = document.getElementById('alwaysFetch');
el.value = el.value ? location.reload() : true;
}, 0);
</script>
This time we no longer rely on the onload event which might conflict with other code elsewhere.
There is HTML5 has History API https://developer.mozilla.org/en-US/docs/Web/API/History
Perhaps you may try that.
Nick Sharp's answer is correct - you are trying to find a solution to a problem you've created by the way you've built the application. There are some potential solutions: Optimistic locking mostly works - but bind the session id not the user id. Alternatively you could rebuild it modelling it along the lines of a thick client application - where all the interaction is mediated by javascript within a single HTML page load.
I am debugging a web application which redirects several times on page load. Page A redirects to page B, which redirects to page C. I don't know what methodology is used (e.g. JavaScript, HTTP redirects, etc.).
What I'm looking for is a debugger to break before a page gets redirected, so that I can inspect exactly what method is being used to redirect, and what data is being sent to next page in the redirect chain.
Is there a simple way to do that? I'm debugging on Windows, so Chrome, Firefox and IE are all available.
UPDATE: It seems that Fiddler is the best option available. I marked the answer from #cgatian as a solution, since his was the Fiddler idea.
In Chrome there is Event Listener Breakpoints -> Sript -> Script First Statement:
Pressing F8 will stop on first statement of any script in page, e.g :
<script type="text/javascript">document.location.href='http://www.example.com'</script>
Also, there is Event Listener Breakpoints -> Load -> beforeUnload but not works in my case.
Alright so it sounds that you want to actually look at variables inside the browser before the redirect occurs. One way I can think of (without modifying the source directly) is to use Google Chrome Snippets.
You could create you're own snippet that binds to the onbeforeunload event.
Step By Step Instructions on Creating a Snippet
Snippet code:
window.onbeforeunload = function(){
var debug;
return;
}
All I am doing in the above code is attaching an event before the browser would be redirected.
If you then place a break point inside your snippet you will be able to break and inspect the variables on the page. (Don't forget to right click your snippet and select Run) before debugging.
In chrome, in the debug window, at the very bottom, are a series of buttons. Click the button that is a dark black circle. It will preserve the log upon navigation. I think that is what you want.
Currently I am developing a web application for which I am using a pre-loader icon. What I want is that the pre-loader becomes visible every time the user navigates to another page or refreshes the page. So far I have the following solution:
window.onbeforeunload = function() { $("applicationdisabler").show(); };
For Safari and Firefox it works fine when the user clicks a link or refreshes the page. However in IE7 the div only becomes visible when the user clicks a link and NOT when the user refreshes the page.
The user can refresh the page by hitting F5 (on Windows) or any other possible way the browser provided.
Of course I have been looking for some workarounds already. The following code shows the alert in IE7, but the div still doesn't become visible.
window.onbeforeunload = function() { $("applicationdisabler").show(); alert("come on!"); };
The code of my div:
<div id="applicationdisabler"><img src="images/preloader.gif" /></div>
Hopefully someone can help me out.
You need to put the # before the id on the jQuery selector:
$("#applicationdisabler").show();
Why not use just use the onLoad listener instead? Although it would be slightly slower it should be more reliable.
Actually after a bit of looking around I'm not sure modifying the DOM makes any sense unless the onBeforeUnload handler returns false first - i.e. forces the user to stay on the same page.
As I understand it the onBeforeUnload event is fired just before the page is unloaded, so if you don't return false the browser will unload the page and DOM, and any JavaScript executed after that will be pointless.
That doesn't quite explain why JavaScript isn't executed properly in the onBeforeUnload function, but from what I've seen sites only use the window.alert or window.prompt dialogs to ask the user if they want to leave the site, and then often executing JavaScript if the user decides to stay.
Hence I'm guessing that some browsers may not allow DOM manipulation when this event is fired - since if the page is unloaded any DOM manipulation done is completely pointless.
So either:
Return false in your onBeforeUnload method, and then show your preloader (although this will stop navigation to the next page)
Use the onLoad event of the next page to show the preloader image instead
Also note: Opera versions 9.5 and below do not support this event (I'm unsure about later versions) but GMail does manage to catch the back button in Opera.
Possibly related is this security warning for IE7's implementation of the onBeforeUnload event - it's possible Microsoft patched it in a way that prevents the things you're trying to do. And I know IE6 and below don't allow commands like document.location='' in the onBeforeUnload handler for security reasons.