Friday, March 23, 2007

iframe.onload doesn't fire for ActiveX controls

Last week I had a few very frustrating days with the web interface of a new application we're building. The web application is basically allowing you to navigate websites as they were at a given moment in time.

The web application is built up from some panels with additional information and a main iframe hosting the actual web page. You type the URL of the page you want to see and presto, there you have it. On the side we'll show you all the other versions of that page we have available. Clicking on one of those versions will bring it up in the iframe.

So far, so good. The problems started when allowing the user to click links in the page that is showing in the iframe. We use a mix of rewriting the HTML before it's shown and intercepting the requests on the server, so that following links actually takes you to the destination as it was at the time that you were looking at. It might sound a bit complex, but it feels a but like time traveling. Imagine the wayback machine, with links working historically.

To update the information in the local panels we hook the onload event of the iframe. And that's where the problems started. Because on some of our systems, the onload event doesn't seem to fire when we open a PDF. It seems to only happen on IE, but not consistently on all our IE systems. A workaround with periodically inspecting the iframe also doesn't work, because somehow we can't even get the URL for the PDFs. And before you ask: yes, the PDFs are served from the same domain as the rest of the page.

It's really frustrating, because when the onload doesn't fire it breaks our UI logic. And the workarounds we've had to do are not pretty and slow the UI responsiveness way more than we'd like.

I've done some searching to see whether other people also had this problem. But of all the questions being posted on iframes, this doesn't seem to be a common occurence. That's why I post it here. Has anyone had the same problem? And if so, what was your solution?

10 comments:

Anonymous said...

Hi, I'm having exactly the same problem - iframe's onload doesn't fire if its src is a PDF (but it works fine if the src is text or HTML). This is with IE 7 on Win XP Pro. Did you find any solution to this?

Regards,
Roddi
roddiwalker [at] yahoo [dot] com

Frank van Puffelen said...

Hi Roddi,
Unfortunately there seemed no way to really solve the problem. We worked around it by doing two things:
1) poll the location property of the iframe window object, instead of waiting for onload to fire.
2) introduce an indirection page before PDFs (and other binaries) are served. The HTML indirection page DOES fire onload and allows us to update the client. The indirection page is served when our content handler detects that it's serving out binary content.

Hope this helps. If you find another solution, I'd be interested to hear about it.

Frank

Anonymous said...

Thanks Frank.
Will certainly let you know if I find another solution.

Regards,
Roddi

wrighty said...

Hi, I am having the same problem - I was wondering if you could post your solution. I have not heard the terms indirection page or poll the location property before.

Thanks
Sara

Frank van Puffelen said...

Hi Wrighty,

Polling the location is pretty simple in javascript. I've set up an example at http://www.vanpuffelen.net/pufprinciple/iframe_onload/page.html . Note that you will only get a location if the page in the iframe is from the same domain as the page containing the iframe.

Setting up an indirection page is a bit more involved. In our case we have a web application that is serving all content from a database. When we detect that we're requested to serve a PDF, we instead serve a normal HTML page that says we are about to download the requested PDF. In that page, we include a link that will download the PDF. This indirection page will then trigger the onload event and will actually also work with the setTimeout function.

It this making it a bit clearer? If not, I can try to set up an example of an indirection page too. But that will take some more effort, since it works best with some server side scripting.

Frank

Anonymous said...

I've just read somewhere else a few minutes ago (it was an old discussion thread in '03) that onload does not work for the iframe and that onreadystatechange should be used instead. I've just tried it myself and it seems to work.

Frank van Puffelen said...

Hi anonymous,

Good one. Hooking onreadystatechange should indeed work.

Frank

Anonimous said...
This comment has been removed by a blog administrator.
Anonymous said...

The problem with the readyState is it only works in IE not FF ...

Frank van Puffelen said...

Thanks, I didn't realize that. That should help reproducing the issue, when we start working on a new version of the product. :-)