12

In Windows operating system i have a custom URI scheme, which is used from

IE, Firefox, Opera, Safari, Google Chrome

to launch Juniper router VPN SSH client (like Cisco). Basically it works as below if the SSH Client is installed, from the web page VPN SSH Client can be launched.

<a href="juniper:open"> VPN SSH Client </a>

Problem:

sometimes the user did not installed the Juniper router SSH client application from the CD/DVD box, therefore the juniper:open does nothing.

So in that case, i need to detect weather or not the URL scheme is available.

Therefore, I tried Javascript method but its not working exactly. because the juniper:open is actually not web link.

How do i then detect it please?

<script>
// Fails
function test1(){
  window.location = 'juniper:open';
  setTimeout(function(){
    if(confirm('Missing. Download it now?')){
      document.location = 'https://www.junper-affiliate.com/setup.zip';
    }
  }, 25);

  //document.location = 'juniper:open';
}

// Fails
function test2(h){
  document.location=h;
  var time = (new Date()).getTime();
  setTimeout(function(){
   var now = (new Date()).getTime();
   if((now-time)<400) {
    if(confirm('Missing. Download it now?')){
     document.location = 'https://www.junper-affiliate.com/setup.zip';
    } else {
     document.location=h;
    }
   }
  }, 300);
 }
</script>

Then:

<a onclick="test1()">TEST 1</a>
<a href="juniper:open" onclick="test2(this.href);return false;">TEST 2</a>

2 Answers2

11

EDIT Following suggestions in comments:

function goto(url, fallback) {
    var script = document.createElement('script'); 

    script.onload = function() { 
        document.location = url;
    } 
    script.onerror = function() { 
        document.location = fallback;
    } 
    script.setAttribute('src', url); 

    document.getElementsByTagName('head')[0].appendChild(script);

}

and

<a href="javascript:" onclick="goto('juniper:open', 'https://www.junper-affiliate.com/setup.zip');">TEST 2</a> 

The price you have to pay, is a duplicated request for the page.

EDIT

This is a good workaround for same-origin policy, which prevents an async version using XMLHTTPRequest to work properly, since SOP restricts cross-domain requests to http and juniper:open would therefore always fail.

function goto(url, fallback) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open('GET', url, false);
    try {
        xmlhttp.send(null);                  // Send the request now
    } catch (e) {
        document.location = fallback;
        return;
    }

    // Throw an error if the request was not 200 OK 
    if (xmlhttp.status === 200) {
        document.location = url;
    } else {
        document.location = fallback;
    }
}

EDIT

The initial solution below doesn't actually work 'cause no exception is being thrown if the protocol is not supported.

  try {
    document.location = 'juniper:open';
  } catch (e) {
    document.location = 'https://www.junper-affiliate.com/setup.zip';
  }
Rakhat
  • 4,783
  • 4
  • 40
  • 50
mlr
  • 886
  • 6
  • 15
  • Not working. When i click the link it straight goes to document.location = 'https://www.junper-affiliate.com/setup.zip'; even the juniper:open is installed. –  Jul 04 '14 at 10:17
  • 1
    What if you use a catch instead of finally? Can you try that? – mlr Jul 04 '14 at 10:19
  • 1
    if i use `catch`, then the `juniper:open` works but when i uninstall from the system `juniper:open` then it does not fall back to https://www.junper-affiliate.com/setup.zip at all –  Jul 04 '14 at 10:20
  • I tried in IE 11, Google Chrome stable, Firefox, Opera, Safari. and its not working with any of them. (i have it not installed like you) –  Jul 04 '14 at 10:24
  • 3
    Can you not try something like this? `var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', 'doesnotexist.js'); script.onerror = function() { alert("Loading failed!"); } document.getElementsByTagName('head')[0].appendChild(script);` –  Jul 04 '14 at 10:34
  • 1
    I see... you are right, no exception is being thrown. I'm coming up with an alternative – mlr Jul 04 '14 at 10:39
  • the xmlHTTPRequest version I had in mind wouldn't work because of same-origin policy, so I used your suggestion about using a script tag (which is a workaround for SOP) and came up with a working version... at least I hope so! Would you mind trying it with Juniper router installed? – mlr Jul 04 '14 at 11:13
  • 1
    Check this answer: http://stackoverflow.com/a/22055638/1676126 it's a bit complicated to obtain cross-browser support, but perhaps it works? – mlr Jul 04 '14 at 12:25
  • can you now show an example. Javascript visits `http://localhost:10001` if failed alert "fail" if success "success". Cause in Local PC i am running a web server which has port 10001 TCP open as web server. –  Jul 07 '14 at 09:26
  • None of these solutions are working for me (Firefox 48) – Paul Haggo Aug 10 '16 at 23:26
  • Your simpler try/catch solution works for me in Firefox 60.4.0esr. – Geremia Jan 24 '19 at 16:49
  • Is this working on https pages? Getting mixed content error. – syonip Aug 06 '19 at 07:54
  • the script tag solution fails on iOS Safari 13.3 with `Failed to load resource: unsupported URL` – diachedelic Feb 20 '20 at 00:57
  • The script solution does not work in Chrome88 `ERR_UNKNOWN_URL_SCHEME` (the URI protocol is registered) – Alex from Jitbit Feb 17 '21 at 15:29
-1

After searching a lot i have not came to anything which can help to solve my problem. But this is what i am now making

1) Write a small tiny webserver which can run in the PC for 24/7 on boot, on crash. Use native python:

python -m SimpleHTTPServer [port]

2) tiny webserver will listen on port abnormal such as 10001 or such TCP ports which never get used

3) from Browser we have to communicate with the http://localhost:10001 just to get a reply

4) based on that reply we have to decide

Otherwise there is no way seems to be available

EDIT: Or you can do this way: InnoSetup - Is there any way to manually create cookie for Internet explorer?

Community
  • 1
  • 1
  • This works in Chrome but not in IE or Firefox. They have to be https://localhost and doing HTTPs opens a whole other host of issues – For the Name Feb 18 '19 at 04:17