When you are using comet forever iframe techniques, you will see the browser throbber of doom keep spinning and showing progress indicator all the time while loading the iframe data. It is the same in IE, firefox, or webkit based browsers like chrome and safari. In order to overcome the problem, you have to handle differently for different browsers.
Firstly, let’s look at how comet was implemented usually.
Normally, in comet iframe, you will define some call back javascript functions in the parent windows, this are javascript functions that are going to be used to update the contents on the web pages when data are pushed from server. On the server side, the server will push html that contains javascript functions calls back to the client. E.g.
Client Side javascript:
In the comet.js:
var iframe = document.getElementById(this.iframe_id);
if(!iframe)
{
iframe = document.createElement("iframe");
iframe.name = iframe.id = "streaming_frame";
document.body.appendChild(iframe);
}
iframe.style.display = "none";
iframe.src = "http://server/action=subscribe&channel=time";
Once the iframe src has been added, the server client communication has started.
On the server side, there are quite a number of open source package for you to choose.grizzly in glassfish, Jetty, Meteor, Node.JS, just to name a few. The example below assumes that you use glassfish as the server:
PrintWriter writer = response.getWriter();
writer.print("");
writer.flush();
Here we write the following line of javascript back to iframe before we push any other data.
function p(data, div_id){parent.p(data, div_id);}
The reason is that when later the data is pushed to the client, the content of the data can be written as
p("10:50pm", "time")
But actually, p is referring to the parent windows call back method p.
Alright, so this is how basically comet works. The following are hacks to different browsers to stop the browser from spinning.
1. Firefox
In firefox, before you trigger the call back method to update the content, you have to create a temp iframe and attach to the document body, then removes it. By keep doing this before you trigger the event, the browser throbber goes away. The modified p function looks like this:
p(data, div_id) {
firefox_hack();
document.getElementById(div_id).innerHTML = data;
}
function firefox_hack () {
var state = pushPage.engine.state;
if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
var fake_iframe;
if (fake_iframe == null){
fake_iframe = document.createElement('iframe');
fake_iframe.style.display = 'none';
}
document.body.appendChild(fake_iframe);
document.body.removeChild(fake_iframe);
}
}
2. Chrome/Safari
For chrome and safari if you just do like above, the forever iframe won’t work at all! There won’t be any data returned from server side. So how do you make comet iframe work in chrome and safari.The hacks lies on server side. There are two conditions that you must fullfill in order to make forever iframe happens in this webkit browsers.
Firstly, the server must push some junk data (around 2k) to the browser before you push the real data. So just write out some javascript comments to the browsers first.
for (int i = 0; i < 10; i++) {
write.print("");
}
Well, I don’t know how big this is going to fill the browser, you may make the loop longer if you can’t make it work.
Secondly, you have to sent the response content type.
response.addHeader("Cache-Control", "private");
response.addHeader("Pragma", "no-cache");
response.setContentType("text/html;charset=ISO-8859-1");
However, my knowledge with chrome and safari is just able to make it work with forever iframe. However, the browser throbber of doom is still there.
3. IE
In IE, if you use above iframe method, it works. I have successfully done that. However in order to stop the browser throbber of doom, you have to make use of the special htmlfile object.
The following code snippet is taken from Alex in his article: What else is burried down in the depth’s of Google’s amazing JavaScript?
// we were served from child.example.com but
// have already set document.domain to example.com
var currentDomain = "http://exmaple.com/";
var dataStreamUrl = currentDomain+"path/to/server.cgi";
var transferDoc = new ActiveXObject("htmlfile"); // !?!
// make sure it's really scriptable
transferDoc.open();
transferDoc.write("");
transferDoc.write("");
transferDoc.write("");
transferDoc.close();
// set the iframe up to call the server for data
var ifrDiv = transferDoc.createElement("div");
transferDoc.appendChild(ifrDiv);
// start communicating
ifrDiv.innerHTML = "";
However, I haven’t really successfully implement this method in IE yet. The problem lies on the javascript call back. It always returns me null object error, when the server returns the following data:
function p(data, div_id) { parent.p(data, div_id)}
I think the problem lies on the parent keyword. In htmlfile, probably you can’t refer to the parent frame just like that. I still need some time to figure out how to do that.





Faced these problems a few years ago while writing a Comet chat system though I used an XMLHttpRequest for Firefox and Opera. The best way I have found to allow the processing function to work in IE is by passing the function into the iframe rather than trying to access the parent, as follows:
// after adding iframe, give it the p function
transferDoc.getElementsByTagName(‘iframe’)[0].p = p;
Also, IE has (or perhaps had) a strange limitation where it will not begin streaming unless the server returns at least 256 characters in the response. You may need to add additional whitespace to the server response.
The thing is that the call back function would be used to modify the parent window DOM.(for example to modify some div content) If you put the definition of the call back method completely in the iframe, then how are you going to access the DOM of the parent window?
If you set
transferDoc.getElementsByTagName(‘iframe’)[0].p = p;
you are giving the iframe a reference to the p function which is defined in the scope of the parent window. The function has access to the parent window DOM (I am not sure whether this works in Firefox since I did not use an iframe in Firefox). With this setup, your server response will look something like this, there is no definition of a local p function:
[256 space characters]
p({some: ‘data’}, ‘someDivID’);
p({more: ‘data’}, ‘someDivID’);
…
The function is called by the browser each time a new script tag is pushed. This works in IE 6-8.
I tried that, but it seems that it gives me “null object” error, when ever then streaming push back p(…) javascript tag. I will check out with that. Anyway, thanks a lot for sharing.
Great blog 9/10! Bookmarked
var state = pushPage.engine.state;
What is this? the variable is not used anywhere. Can it be the reason the firefox ‘hack’ does not work for me?
thanks
This is the script that I used in my comet streaming that can control the state of streaming, whether it is initializing or running etc. You can ignore this.
So has anyone figured out a way to get Chrome to stop spinning when streaming to a hidden frame? I’ve been unsuccessful.
Well, so far i didn’t see anyone who has a solution for this as well. Even the lightstreamer also has this problem with chrome.http://www.lightstreamer.com
It’s even easier in Firefox (4 beta, haven’t tested 3.6): load the iframe on window.onload. It also works in IE7, IE8 and IE9 beta. I’m not sure about IE6, don’t have it native.
I found it I do the first poll with a setTimeout — chrome will stop spinning. Odd because I don’t call the first ‘poll’ until after I get the dom:loaded event — but it seemed to make the cursor go away
Hi Jim, would you please share your codes which stop the spinning? Thank you!
setTimeout is working for the first poll.if you re initiate the poll chrome shows spinning. any ideas jim.
One way to stop the browser spinning is to smash the monitor in with a hammer. Enjoy!
I am an admirer of your website. Persist in up the good work.
i am facing the throbbing problem in chrome when i am reinitiating the forever iframe . any ideas?
best css codes.
So do you have found the solution how to stop the loading spinning indicator?
Unfortunately not for other browsers except firefox. I found that google finance is also using comet streaming, and it also has the spinning indicator. So i think that maybe it is really necessary to figure out a way to remove it as this gives the users an indication that the streaming is working. If this stopped, then there may be some problem.