14
Jan/09
1

Don’t use “name” as global javascript variable! (IE Bug)

IE Bug Yesterday I spent several hours tracking a problem with the Nagios GUI in connection with a NagVis map in Internet Explorer. The problem occurred when opening a NagVis map in the default Nagios frame set. After loading the map all links in the sidebar were opening in a new window in Internet Explorer instead of the frame named “main”. More fun: When I had opened another page in a second tab which has a frame named “main”, the linked pages from the Nagios sidebar open in the frame of the second tab.

I was searching a lot to get a lead to the problem. First I thought about some invalid HTML code – that was all fine. After that I thought the problem was caused by a wrong doctype in the Nagios frameset. . Then I used the DOM Inspector for Internet Explorer to inspect the DOM tree in IE. There I recognized the frame named “main” was renamed right after loading the page. And it did not happen when there were no objects on the NagVis maps. So it was clear to me: The problem was that something changed the name of the frame and this happened somewhere in the new JavaScript object parsing code of NagVis.

Finally I found the problematic code and solved it in current NagVis code. Now read more about how to reproduce that problem by a simple example.

First I have some example files which will make you able to reproduce the problem. After you got the code I’ll explain the problem.

Here the code of a simple example to reproduce that behavior. Easily create all these files in one directory and open the index.html in your browser (You need to use Internet Explorer to reproduce that bug ;-) ):

index.html:

<HTML>
<HEAD></HEAD>
<FRAMESET BORDER="0" FRAMEBORDER="0" FRAMESPACING="0" COLS="180,*">
<FRAME SRC="side.html" NAME="side" TARGET="main">
<FRAME SRC="main.html" NAME="main">
</FRAMESET>
<NOFRAMES>These pages require a browser which supports frames</NOFRAMES>
</HTML>

linked.html:

<HTML>
<HEAD></HEAD>
<BODY>
<p>Linked page. Should open in &quot;main&quot; frame.</p>
</BODY>
</HTML>

side.html:

<HTML>
<HEAD></HEAD>
<BODY>
<a href="main.html" target="main">Main Page</a>
<a href="linked.html" target="main">Linked Page</a>
</BODY>
</HTML>

main.html:

<HTML>
<HEAD></HEAD>
<BODY>
<script type="text/javascript">
<!--
 
function foo() {
	name="xyz";
 
	// Do sth. with name...
}
 
//-->
</script>
<h1>Main page</h1>
<p>Navigate with the sidebars links. Everything should work.</p>
<p>Now click the link to <a href="javascript:foo()">create the bug</a>.</p>
<p>After hitting the above link navigate with the sidebars links again. All links should open in a new window in IE7.</p>
</BODY>
</HTML>

When opening the index.html you got the main.html in main frame of the frame set. When you look at the code of main.html you see the javascript function called foo(). This functions sets the variable name to the value “xyz”. It’s important to notice that there is no initialization of that variable.

Now you know that the parent frame of main.html is named main. Look, in IE this results in a global variable in javascript code of main.html which is called name. You don’t believe? Uncomment the alert() call in foo() and call the index.html. You will get an alertbox which tells you the contents of the variable name: “main”. You can now comment out the alert() call again.

We know that the name of the frame is a global variable in the framed document. Now you can imagine what the result of the foo() call is? You’re right. The global variable name is set to “xyz”. This results in a renamed frame. The frame is named “xyz” from now.

Now that we have no frame “main” anymore the Internet Explorer opens the links in new windows or new tabs – depending on your IE configuration. You can prevent this problem by:

a) Renaming the variable to sth. other than “name”. b) Much better: Declare your variables! Just a simple “var name;” before the first usage of the local variable would avoid such problems.

In the moment you declare the variable in the function context you create a function local variable which is only valid in the function context. After leaving the function the variable is cleaned. It will not override the global name variable.

Lessons learned:

  1. What ever you do: Declare all your variables!
  2. Don’t use such variables with the name “name” in global javascript context.
Filed under: Javascript
Comments (0) Trackbacks (1)