Groovy ’60s Sounds from the Land of Smile!

Thursday, February 2, 2006

Troubleshooting Javascript

I ran into an interesting problem recently involving Javascript and a marketing e-mail. I’ll change some details, but the concepts are the same.

We were developing a form for people to fill out in response to an opt-in e-mail marketing campaign, and wanted the form to be reusable for future campaigns. The server in question doesn’t run any dynamic language like PHP or JSP or such, so we were limited to HTML and Javascript. The e-mail is sent out as HTML e-mail with links embedded in it to lead to the form. The links contained information such as an ID for the campaign (not for each user, just to identify which campaign the form was being used for), like so:

http://www.example.com/foo.html?campaignID=123456

When the HTML for this e-mail was on our server, the links worked fine, but when we tested it in actual e-mail, some users got error messages and a blank page instead of our form. If you reloaded the page, it would work.

I was able to duplicate the problem. I had Microsoft Script Debugger installed, so I got more detailed error messages than the users, messages that permission to read some information was being denied.

The problem, it turned out, was that when Internet Explorer had its security settings increased to a certain (recommended) level, if the page was linked from somewhere other than the server containing the page being linked to, Javascript considered certain data tainted and wouldn’t allow scripts to access that data, including the URL and the parameters embedded in it. Perfectly justifiable, makes complete sense from a security standpoint, and I wish the browser did that at all security levels.

Reading up on this in Danny Goodman’s Javascript Bible, I found that if the two machines in question are in the same domain, for example, www.example.com and search.example.com, you can work around this by setting document.domain to the top level domain they have in common, like so:

document.domain = "example.com";

In this case, this didn’t work. It only works when the machines are in the same top level domain, and when you click on a link in an e-mail message, it may have no domain associated with it at all. In a marketing message like this, the domain almost certainly wouldn’t be the same, anyway, so we had to find a workaround, one that didn’t involve grabbing information from the URL.

The answer was to change the links within the e-mail to link to a separate HTML page for each campaign. That page would use Javascript within the head section to set the variables we had previously tried to set in the URL, and would then redirect to the form. The code looked something like this:

<script type="text/javascript">
<!--

var campaign = new Array(4);
campaign[0] = 123456;
campaign[1] = http://www.example.com/url1.html;
campaign[2] = http://www.example.com/url2.html;
campaign[3] = yes;

var url = "http://www.example.com/foo.html?" + 
   campaign.join("&"); //this is one line

location.href = url;

//-->
</script>

This way, we didn’t have to make any changes to the form, which had already been through testing and was working, and we didn’t have to create a new form page for each campaign link, just this a new one of these small configuration files. Since the link to the form is now coming from the same server that the form is on, the form can access the required information.

It’s not an ideal solution; it requires the user have Javascript turned on, for example, but since the form itself also required Javascript, I figured it was an acceptable move. In something like PHP, instead of doing this, I would still be able to read the data, but would sanity check it to make sure it wasn’t doing something harmful, then if not, use it. But with these server limitations, this approach seems to work. If anyone out there has any better suggestions that fit within the limitations of HTML and Javascript only as mentioned above, though, I’m all ears.

Posted at 11:55 AM

Comments

This site is copyright © 2002-2024, Ralph Brandi.