views:

3602

answers:

7

I do some minor programming and web work for a local community college. Work that includes maintaining a very large and soul destroying website that consists of a hodge podge of VBScript, javascript, Dreamweaver generated cruft and a collection of add-ons that various conmen have convinced them to buy over the years.

A few days ago I got a call "The website is locking up for people using Safari!" Okay, step one download Safari(v3.1.2), step two surf to the site. Everything appears to work fine.

Long story short I finally isolated the problem and it relates to Safari's back button. The website uses a fancy-pants javascript menu that works in every browser I've tried including Safari, the first time around. But in Safari if you follow a link off the page and then hit the back button the menu no longer works.

I made a pared down webpage to illustrate the principle.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com"&gt;Coding Horror</a>
</body>
</html>

Load the page and you see the alert box. Then follow the link off the page and hit the back button. In IE and Firefox you see the alert box again, in Safari you do not.

After a vigorous googling I've discovered others with similar problems but no really satisfactory answers. So my question is how can I make my pages work the same way in Safari after the user hits the back button as they do in other browsers?

If this is a stupid question please be gentle, javascript is somewhat new to me.

A: 

I have no idea what's causing the problem but I know who might be able to help you. Safari is built on Webkit and short of Apple (who are not so community minded) the Webkit team might know what the issue is.

It's not a stupid question at all.

Teifion
A: 

I've noticed something very similar. I think it is because Firefox and IE, when going back, are retrieving the page from the server again and Safari is not. Have you tried adding a page expiry/no cache header? I was going to look into it when I discovered the behaviour but haven't had time yet.

Stacey Richards
+5  A: 

@Autodidact: It's definitely not a stupid question, any time when the behaviour of webkit differs from both IE and Firefox is a bug a should be filed at http://bugs.webkit.org (I would file it myself, but then i'd be the one who had to confirm the fix, rather than you, which would be rather silly given you're the person experiencing this bug :D) [Edit: I just realised that your example will be in the back/forward cache -- the onload won't fire again as the entire JS state will be stored, it seems unlikely in this case that that is causing a bug, so when you file a bug report, if at all possible you should try to include the code or the url that fails]

@Teifon: Um, Apple engineers do almost all of the active development on WebKit (WebKit is a MacOS system framework after all, and apple started the project (as a fork of khtml, but they are now substantially diverged)), non-apple developers focus almost entirely on their respective back and front ends (eg. gtk, qt, wx) -- if you look at http://trac.webkit.org/ you can see that fairly clearly the majority of dev work is from apple -- and the most active irc-ers are apple engineers, so i'm really not sure how you've come to the conclusion that webkit is somehow community minded when apple is not :D (Sorry for long reply, I'm just tired of seeing this particular misconception repeated :-/ )

[Edit: @Stefan Koenig I believe that any place where the caching behaviour differs from IE and Firefox in a way that actually breaks a site is a bug]

olliej
+5  A: 

An iframe solves the problem:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com"&gt;Coding Horror</a>
<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
this prevents back forward cache
</iframe>
</body>
</html>

more details

Stefan Koenig
+1  A: 

You can also use jQuery's $(document).ready() to fix this issue in Safari. It has several other advantages over an inline onload event as well.

travis
+3  A: 

Stefan's iframe solution works, but if that's not elegant enough, I find the following JavaScript also solves it:

window.onunload = function(){};

That is, if your menu is JavaScript, then you might prefer to solve this issue with JavaScript too.

The unload event handler definition idea came from this Firefox 1.5 article: https://developer.mozilla.org/en/Using_Firefox_1.5_caching.

Lee Kowalkowski
A: 

I know this thread is a year old, but I just fixed an identical Safari-only problem using ProjectSeven's Safari backbutton fix. Works like a charm.

http://www.projectseven.com/extensions/info/safaribbfix/index.htm

Llamabomber
Its funny because ProjectSeven was the javascript menu I was talking about. Eventually ditched it for a homemade jquery one. Moving from onload in the body tag to jquery's document.ready solved the issue for me.
Autodidact