NOTE: An update to this article has been posted and can be found here - Take 2 (thanks Firefox 3.5)
After quite a bit of testing and head scratching, we were able to come up with the following table of events to expect when dynamically loading content into an iFrame:
What is Content-Disposition?
Sometimes when you provide your users with a file download link from a web page, you might not be linking them directly to the file, but to an ASPX page or PHP script instead, which streams the content of the file back to the client. In order for your browser to know what to do with this content, you provide header information with the response including Content-Type and Content-Disposition.
Content-Type is exactly what it sounds like: "application/pdf" if the content is PDF, "image/jpeg" if the content is JPEG, and so on. Content-Disposition refers to how you want the browser to handle the file after it is downloaded. It comes in a few flavors, but these are the ones that matter for this article: "inline" where the browser will attempt to load it (or an application that can load it) in the browser window or frame specified, and "attachment" where the browser will prompt the user to download.
The table above is for quick reference. I'm sure I'm going to need to Google for this answer in the future, so, "You're welcome, future-self." Here's a breakdown of each browser and what events should be expected and when they fire.
Safari / Chrome
Inline: The onload event fires when the content is fully downloaded (but its associated application might not be done loading the file).
Attachment: ... thanks for nothing. Neither of these browsers provide any events for iFrames loaded with content that have an "Attachment" disposition type.
Inline: This behaves identically to Safari / Chrome in the Inline case.
Attachment: This also behaves identically to Safari / Chrome in the Inline case.
IE (surprisingly gets my vote of approval here) There is an onreadystatechange event that fires whenever the iFrame's readyState property changes. That readyState reflects where the download is in the process.
Inline: When you initially set the src value of the iFrame element, the readyState changes to loading. When the file has completely downloaded, the readyState changes to interactive. The big difference between IE and the other browsers is that IE then changes the readyState property to complete when the page (or application) is fully loaded and ready for the user.
Attachment: This behaves identically to the Inline case of IE, but the readyState property never changes to complete. That wouldn't make much sense, since the user has to manually open the file by double-clicking on it or opening it from some application.
As you can see, this can be quite a pain; but with a little bit of research and knowing exactly what you want your customers to experience, you can have a fairly consistent process for all browsers.