2

I'm building a web kiosk. The computer boots and goes right into Chrome. The browser loads before a network connection is established, so the first thing a user always sees is a connection error.

I'm trying to make an initial, locally hosted webpage that waits for the connection to be up, then redirects the page to the live webpage hosted on the network.

I've tried:

navigator.onLine

But in Chrome this only checks if the browser is in 'online mode,' not if there is actually a working connection. The result is that it always redirects to the live page with no connection and the users get a connection error.

I've tried AJAX requests, but the result is always:

Origin http://localhost is not allowed by Access-Control-Allow-Origin

I can't boot Chrome with any flags to disable this. It has to be the default flavor of Chrome.

So my question: Is there a working solution to this problem? I am willing to use any combination of Javascript / JQuery / PHP / HTML , etc.

Here is the code for my locally hosted web page:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Kiosk Splash</title>
  <link rel=stylesheet type="text/css" href="jquery/css/ui-lightness/jquery-ui-1.10.2.custom.css">
  <script src="jquery/js/jquery-1.9.1.js"></script>
  <script src="jquery/js/jquery-ui-1.10.2.custom.js"></script>
</head>
<body>
<div id="dialog" style="text-align:center;">
    <p>
        <font font face="verdana" size="5">The Kiosk is establishing a connection to the network...</font>
    </p>
    <div id="progressbar" style="width: 50%; margin: 0 auto;"></div>
</div>
<script>
$( "#dialog" ).dialog({ minWidth: 1000 });
$(".ui-dialog-titlebar-close", this.parentNode).hide();
$( "#progressbar" ).width(800);
$( "#progressbar" ).progressbar({
  value: false
});
      function connect(){
      try{
        $.ajax({url:"http://intranet/webpage",
        statusCode: {
    200: function() {
      window.location.replace("http://live/webpage");
    }
  },
     error: function(e){
         console.log(e);
         setTimeout(connect, 5000);
     }, 
       dataType:"json"
   });
}catch(e){
     console.log(e);         
    setTimeout(connect, 5000);
}
} 
connect();
</script>
</body>
</html>
Taj G
  • 393
  • 1
  • 4
  • 16
  • 1
    you need to run a web server (php or other sside language) on the pc to proxy the ajax request – David Fregoli Mar 21 '13 at 16:12
  • Can you run a local webserver? You could try running node.js on localhost and serve a local page from there; your node server could try to test for connectivity on the backend (bypassing Chrome's security). Once connected, the node server could push a notification to the browser. –  Mar 21 '13 at 16:14
  • Look at the answer for Origin http://localhost is not allowed by Access-Control-Allow-Origin here :- See if it helps. http://stackoverflow.com/questions/15534640/ajax-origin-localhost-is-not-allowed-by-access-control-allow-origin/15537999#15537999 – PSL Mar 21 '13 at 16:16
  • why not just delay the chrome? another thing is that network is on delayed startup mode, you could move that to somewhere earlier – Imre L Mar 21 '13 at 16:26
  • @Imre L, the issue is that our DHCP server takes a long time to issue an IP, it's not the startup mode of the computer. Setting a Static IP avoids the problem, but we're trying not to do that. – Taj G Mar 21 '13 at 16:28
  • 1
    what I would do is set up a while loop with a recursive ping and open chrome AFTER the ping returns something implying internet connectivity. – RandomUs1r Mar 21 '13 at 16:55
  • @RandomUs1r we need our browser kiosk to launch immediately so that the computer is locked down. We don't want people to be able to mess about on the machine. – Taj G Mar 21 '13 at 17:01
  • Gotcha, when chrome launches, it then tries to go to your webapp right? – RandomUs1r Mar 21 '13 at 17:06
  • @RandomUs1r Yes, Chrome is the browser in the kiosk app were using: OpenKiosk. Once there is a network connection, it should redirect to the webapp we're hosting on our intranet, which has links to the internet – Taj G Mar 21 '13 at 17:13
  • what I would do then is add a page on the localhost of the kiosk, have that page do the ping and then redirect to the intranet app from there. I'd do all that by setting Chrome's default page to the localhost page. – RandomUs1r Mar 21 '13 at 17:28
  • @RandomUs1r Yeah, we're back to square one, then. He needs the machine to have a local webserver to process any network request, or else he'll run into the domain issue. –  Mar 21 '13 at 18:10

2 Answers2

2

A quite dirty hack with JSONP and jquery

using jsfiddle jsonp test:

(function testConnection() {
  setTimeout(testConnection, 2000);
  $.getJSON("http://jsfiddle.net/echo/jsonp/?callback=redirect&cb=?");
})()

function redirect() {
   window.location = 'http://www.google.com'; // REDIRECT TARGET
}

first version:

(function testConnection() {
    setTimeout(testConnection, 2000);
    $.getJSON(
       "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
       {format:'json'}
    ).done(function(result){
        window.location = 'http://www.google.com'; // REDIRECT TARGET
    });
})()

Works as expected, you might wanna have your own your own web server in order not to rely on a specific API

David Fregoli
  • 3,377
  • 1
  • 19
  • 40
  • Nice try, but flickr is blocked in our office by web filtering. Also, I'm just guessing, this will cause the same Acces-Control-Allow-Origin error. – Taj G Mar 21 '13 at 16:31
  • just find another jsonp api that's not blocked, or make your own page. same origin policy is not a problem since it's a jsonp request – David Fregoli Mar 21 '13 at 16:33
  • +1, this is what I would suggest. Just a simple page that echoes `loadPage();` if it can be reached, and nothing otherwise. – Julian H. Lam Mar 21 '13 at 16:43
  • @DavidFregoli I don't have any experience writing jsonp api to make my own page. Could you point me in the right direction? Your solution works, but I'm hesitant to rely on an external website that could change their address. – Taj G Mar 21 '13 at 17:04
  • hehe you don't need to write an API, just an URL (even a static file) that returns 'redirect()' and invoke it like 'www.domain.com/file.txt?cb=?' – David Fregoli Mar 21 '13 at 17:09
  • @DavidFregoli how can you name a txt file with '?' in it? – Taj G Mar 21 '13 at 17:12
  • file.txt is the filename, file.txt?cb=? is how you call it in the js (jQuery will automatically translate requests ending in ? as jsonp and execute their content as javascript) – David Fregoli Mar 21 '13 at 17:13
  • @DavidFregoli It works! Thank you! Hosting the txt file is a very elegant solution, it works, thanks for bearing with me. – Taj G Mar 21 '13 at 17:29
  • cool, just make sure no one manages to edit it or he'll be able to execute any javascript on the client :D ( in fact you can have the window.location command on the txt file itself so that it's centralized and an edit will affect all the clients ) – David Fregoli Mar 21 '13 at 17:32
0

This behavior is intended to protect from a malicious script connecting from localhost, of course when you are trying to implement a kiosk this is just a pain.

I THINK what you need to do is the same as the answer in this rather different question: Origin is not allowed by Access-Control-Allow-Origin

Matt Mombrea suggests something like this:

Access-Control-Allow-Origin: *

"This will allow cross domain AJAX. In PHP you'll want to modify the response like so:"

<?php header('Access-Control-Allow-Origin: *'); ?>

You can then poll the online server you control that responds with this access control allowance to see if your internet connection is on yet.

Otherwise you could use a localhost PHP server script to try to access a server, and have your ajax localhost page query the localhost script for the answer.

Community
  • 1
  • 1
BrianH
  • 2,140
  • 14
  • 20