Javascript (?) help - need to check connectivity

From: Dan (HERMAND) 3 Sep 2011 12:43
To: ALL1 of 18

Hi All,

 

Didn't really know how to word that title. I'll summarise what my problem is, as someone may have a more elegant solution. I've just set up some 200 Wyse thin client devices. When they boot, the user gets a Kiosk mode IE8 (Or IE7, I don't recall :$) page which directs to the Citrix web interface.

 

Only problem is that these devices are Wireless and on many of them, the Wireless doesn't sort itself out quickly enough so the user gets a 404 and has to hit F5 to get the page.

 

What I want is a simple webpage, hosted locally on the devices, that will just say "Please wait..." or whatever, while checking for connectivity to the 'real' website. As soon as the real website is there, it redirects the user.

 

What would be the best way to do this? It needs to be mega simple in terms of number of files. Wyse has a horrendous scripting language, so the idea of copying over the JQuery libraries etc fills me dread. Not to mention the old IE issue! I'm stuck with IE as it has the best compatibility with Citrix's fancier features.

 

Any and all help much appreciated!

From: Peter (BOUGHTONP) 3 Sep 2011 13:13
To: Dan (HERMAND) 2 of 18
There's only one jQuery library, and it's one 30KB file, and it makes this so simple compared to what it would be (especially since I can't be arsed looking up the specifics of IE's XHR stuff).

Besides, you don't even need to copy files. Just convert it to base64 and use the data protocol direct in the HTML. Like in the attachment.

And then do something like this:
javascript code:
var ConnAttempts = 0
var $j = jQuery.noConflict()
 
$j(document).ready(init)
 
function init()
{
     $j('body').append('<div id="status-msg"></div>')
     checkConnectivity()
}
 
function checkConnectivity()
{
     $j('#status-msg').text('Trying to connect...')
     ConnAttempts++
 
     var TargetUrl = 'http://whatever'
 
     $j.get( TargetUrl , handleUrlResponse )
 
     function handleUrlResponse(data,status)
     {
          if (status == 200)
          {
               // Hooray! Lets go redirect
               location.href = TargetUrl
          }
          else
          {
               // Boo! Still not ready
 
               if ( ConnAttempts > MaxConnAttempts )
               {
                    $j('#status-msg').text('Received status '+status+' after '+ConnAttempts+' tries.')
               }
               else
               {
                    $j('#status-msg').text('Please wait...')
 
                    setTimeout( checkConnectivity , 300 ) // 0.3 seconds
               }
          }
     }
}


Which is untested because I'm lazy, but unless I've made any stupid mistakes it should do what you want.
EDITED: 3 Sep 2011 13:19 by BOUGHTONP
From: Peter (BOUGHTONP) 3 Sep 2011 13:25
To: Dan (HERMAND) 3 of 18
I decided to test it, and I appear to have done something stupid, because it's not working. :'S

Oh fucking Microsoft! :@

quote:
Microsoft has limited its support to certain "non-navigable" content for security reasons, including concerns that JavaScript embedded in a data URI may not be interpretable by script filters such as those used by web-based email clients. Data URIs must be smaller than 32 KiB in Version 8.


So because Microsoft are shit and can't write a decent email client, they cripple the browser and apply arbitrary limits. :@
EDITED: 3 Sep 2011 13:31 by BOUGHTONP
From: Dan (HERMAND) 3 Sep 2011 13:36
To: Peter (BOUGHTONP) 4 of 18
Gay, but you have persuaded me to suck it up and use JQuery. I shall have a play, thanks :)
From: Peter (BOUGHTONP) 3 Sep 2011 13:41
To: Dan (HERMAND) 5 of 18
I tried going with the native XMLHttpRequest stuff and it's not doing anything sensible. :(

You said before you weren't sure if it's IE7 or IE8 - you're going to need to verify that, because this may count as a cross-domain request in the final thing, and Wikipedia suggests that only IE8+ accepts the headers that let you do that.
From: Dan (HERMAND) 3 Sep 2011 13:45
To: Peter (BOUGHTONP) 6 of 18
Just checked and it's IE7. At the minute, I need to assume it has to stay that way :(
From: Dan (HERMAND) 3 Sep 2011 14:08
To: Peter (BOUGHTONP) 7 of 18
I've found this sort of thing:

code:
<img alt="Connecting..." id="ImageTest" />
 
<script type="text/javascript">
 
$('#ImageTest')
  .error(function() {
    alert('Handler for .error() called.')
  })
  .attr("src", $imageURL);
 
 
</script>


It seems to work, though I've not tested it in IE7 yet. Only I'm too thick to figure out how to keep on retrying
From: Peter (BOUGHTONP) 3 Sep 2011 14:26
To: Dan (HERMAND) 8 of 18
Use setTimeout to call itself after a short pause.

javascript code:
function setImageUrl()
{
$('#ImageTest')
  .error(function() {
    alert('Handler for .error() called.')
    setTimeout( setImageUrl , 300 )
  })
  .attr("src", $imageURL);
}
 
setImageUrl()



I guess this will work in IE7 since the image is doing the cross-domain stuff, not the script, so there's no security issues.

Hmmm, might also need to set the src to a safe value and then back to the test one for it to trigger a change. (Not sure on that.)
EDITED: 3 Sep 2011 14:29 by BOUGHTONP
From: Dan (HERMAND) 3 Sep 2011 15:54
To: ALL9 of 18
Using images seems to lock up the browser when I do it in any kind of loop :(
From: Peter (BOUGHTONP) 3 Sep 2011 16:24
To: Dan (HERMAND) 10 of 18
Browsers suck. :|

Instead of looping, could you try multiple images, with each src set in a chain after the previous one fails?

Oh, and make sure IE's shit local caching is disabled (i.e. "check every visit").
From: Dan (HERMAND) 3 Sep 2011 16:25
To: ALL11 of 18
Right, I'm getting there but if I change a variable in ".Error" it doesn't seem to make any difference. Is that by design?
From: Peter (BOUGHTONP) 3 Sep 2011 16:27
To: Dan (HERMAND) 12 of 18
Should be lowercase e for error?
From: Dan (HERMAND) 3 Sep 2011 16:42
To: Peter (BOUGHTONP) 13 of 18
Think I've sussed the problem, maybe. I've added a "didError" variable and set it to one when the error occurs. However, because it's not triggering UNTIL the error, my code is going ahead and executing before the image has failed
From: Dan (HERMAND) 3 Sep 2011 16:52
To: Peter (BOUGHTONP) 14 of 18
code:
function checkImageUrl()
{
 
$('#ImageTest')
  .error(function() {
  setTimeout("checkImageUrl()", 2000);
  })
 
  $('#ImageTest').load(function() {
  window.location.replace(redirectURL);
  });
 
  $('#ImageTest').attr("src", imageURL + "?=" + d.getTime());
 
}
 
checkImageUrl();


Trial and error, yay!
From: Dan (HERMAND) 3 Sep 2011 16:55
To: Dan (HERMAND) 15 of 18
Hmm, this does work but looking at it in FireBug, it appears to exponentially load images and I'm not really sure why :(
From: Dan (HERMAND) 3 Sep 2011 17:06
To: Dan (HERMAND) 16 of 18
Ah, every time the function is called I'm creating a new event handler. Moved them out of the function and I think I'm there.
From: Peter (BOUGHTONP) 3 Sep 2011 17:14
To: Dan (HERMAND) 17 of 18
Yay!

Course once you switch to IE7 you'll probably find some random annoying error cropping up just to be a pain. :(
From: Dan (HERMAND) 3 Sep 2011 17:24
To: Peter (BOUGHTONP) 18 of 18

You were right :D Just does nothing after the first event in IE, I guess changing the image url doesn't force a reload of the image.

 

I have, however, got it working by forcing a page refresh. I'll try and figure out how to get IE to reload the image because it's much cleaner, but at least I can make it work regardless.