0

We have a web site where we use iframe to load some data (iframe long polling). This data can be loaded automatically, e.g. every 2 minutes. When this web site is opened in IE (tried in latest 9 version) it will send request each 2 minutes. That's okay.

But when we open another browser (or program) and IE is not in focus - during each request IE will grab a focus to itself...

Maybe somebody know how to fix this (prevent IE to steal the focus)? As I understand Ajax requests can fix this, but this can be difficult to update...

Update:

From server (in Iframe) we return something like this:

<html><body>
<script>parent.MailChecker.updateStatus({"s":"Connecting to xxx@gmail.com...","p":0,"c":null,"e":false})</script>
<script>parent.MailChecker.updateStatus({"s":"Preparing to fetch emails...","p":0,"c":null,"e":false})</script>
<script>parent.MailChecker.updateStatus({"s":"Downloading 1 email from 35...","p":2.8571428571429,"c":null,"e":"784"})</script>
<script>parent.MailChecker.updateStatus({"s":"Downloading 2 emails from 35...","p":5.7142857142857,"c":null,"e":"784"})</script>
...
<script>parent.MailChecker.updateStatus({"s":"Done!","p":100,"c":"0","e":false})</script>
</body></html>
Andron
  • 6,413
  • 4
  • 43
  • 56
  • IFRAME (forever frame or long-polling) are old solutions to this problem. The most common solution is to us the `XMLHttpRequest` object to achieve what you are looking to do. If you take this approach you won't see the same focus problem. – leggetter Nov 24 '11 at 12:49
  • In my case I return js (which will be called automatically) into the frame, so I don't think that I can use Ajax to do similar things... – Andron Nov 24 '11 at 14:34
  • Forever frames do work in the way you describe (they execute script, normally a single call into the page from the IFRAME) so you would need to rework your code so that only data was sent of the connection. Maybe instructions which indicated what functionality should be executed? – leggetter Nov 24 '11 at 14:53
  • We use iframe to check emails list and in this request we return current status of emails checking (percentages, total count, etc.) via js code (automatically updates progress bar). – Andron Nov 24 '11 at 16:02
  • Great! You can return something like the following JSON from the XHR request: `{ "percent" :55, "totalCount": 355, "otherValue": "I'm another value" }` as a string and parse it into a JavaScript object using [JSON.parse](https://github.com/douglascrockford/JSON-js/blob/master/json.js#L438) (natively available in most/all modern browser). And then do the UI updates as you presently do. It doesn't sound like a big job and it will remove your focusing problem. – leggetter Nov 24 '11 at 20:32
  • I need return all 'percentages' at once - via one request. I cannot send several requests to server to check current state. – Andron Nov 25 '11 at 10:41

1 Answers1

0

Changing from an IFRAME technique to using an XMLHttpRequest solution (used by thousands of sites/web apps) will remove your focus problem. This technique is used by many Comet servers some of which are listed here.

As discussed in the comments, you should use an XHR request (long polling or streaming) so that you can push updates from the server to the client containing just the data. You can use HTTP Long-Polling or HTTP streaming using an XMLHttpRequest (XHR) object. From the above you can see the data just looks as follows:

{"s":"Connecting to xxx@gmail.com...","p":0,"c":null,"e":false}

And later, when the status changes push another update along the connection e.g.

{"s":"Preparing to fetch emails...","p":0,"c":null,"e":false}

The handler for the XHR can then check the XHR.responseText and parse out the update values. If you are using long-polling this is as simple as:

var update = JSON.parse(xhr.responseText);
MailChecker.updateStatus(update);

If you are using XHR streaming then you'll also need to parse out the previous updates from the XHR.responseText since it keeps growing in size. More info on HTTP Streaming here: http://ajaxpatterns.org/HTTP_Streaming

leggetter
  • 15,248
  • 1
  • 55
  • 61
  • So e.g. on mail server there are 100 email. As result - we'll send 100 or more Ajax requests to see a progress? Now there is only one request... That's why iframe was used for this. – Andron Dec 02 '11 at 09:58
  • 1
    @Andron - A single **persistent** connection is created. Then, as new data becomes available (the progress of the email processing changes) your server can push updates to the web browser. If required you can send multiple updates in one push (maybe an Array of updates). The point is, your `iframe` solution is causing a problem, it's probably not the right solution, and using an `XMLHttpRequest` object is probably the best solution for you. I'd recommend you read [Push Technology](http://en.wikipedia.org/wiki/Push_technology) and [Comet](http://en.wikipedia.org/wiki/Comet_(programming)). – leggetter Dec 07 '11 at 12:01
  • thanks for answer, but requirements for project are that we cannot install anything special (e.g. for comet). So do you think this can be done via 'XMLHttpRequest' response? Maybe you have an example... :) – Andron Dec 08 '11 at 15:22
  • Comet doesn't require any special installs. It's a paradigm, an umbrella term which also covers what you are doing via an IFRAME. You can of course use a dedicated Comet/realtime server if you want to - and it's probably good practice. You can see a related question [here](http://stackoverflow.com/questions/7213549/long-polling-http-streaming-general-questions) and an example [here](http://www.leggetter.co.uk/stackoverflow/7213549/index.html)(view source for JavaScript), but you'll need to play with the code to fix the buffering problem. – leggetter Dec 08 '11 at 16:36