How to Detect Custom Protocol with Javascript


Senzon
Member
Registered: 25.05.12 19:13
Timezone: UTC +3
Posts: 19

Let's say I have a custom protocol called "testprotocol" and I want to make a request with it when a user clicks a button like this:

testprotocol://param1=test

But I want to check first if the user has my protocol installed before trying to use it (because if they don't they get an error page), and if they don't have it I want to send the user to a page where they can install it instead. How can I check this using Javascript?


ynori7
Administrator
Registered: 24.08.11 12:16
Timezone: UTC +2
Posts: 164

I actually researched this pretty recently and found a ton of results saying that there is no simple way to do this for all browsers, but I created a solution which seems to work so far pretty well:

<html>
<head>
</head>
<body>
<script>
function startProtocol(){
  ifrm = document.createElement("iframe");
  ifrm.setAttribute("src", "testprotocol://dosomething?param1=true");
  ifrm.style.display = "none";
  ifrm.onerror = getProtocol;
  document.body.appendChild(ifrm); 
}
function getProtocol(){ 
  if(confirm('You do not seem to have the TestProtocol installed, do you want to go download it now?')){
    document.location = 'http://www.halls-of-valhalla.org/getTestProtocol';
  }   
}
</script>
<a href="#" onclick="startProtocol()">Launch The Test Application</a>
</body>
</html>

I might add it to the codes section too because it's kind of a useful little technique.

i537.photobucket.com/albums/ff338/ynori77/archenemysig1.jpg


Senzon
Member
Registered: 25.05.12 19:13
Timezone: UTC +3
Posts: 19

Works awesome for Firefox and Chrome, but unfortunately not for Internet Explorer. It seems that when you have an iframe with an invalid src, IE decides to just redirect you to that src, which is exactly the opposite of what would make sense to do. But not surprising knowing IE.

Any ideas how to do this in IE?


ynori7
Administrator
Registered: 24.08.11 12:16
Timezone: UTC +2
Posts: 164

Hmm, true. I didn't test it in IE originally because I was on a Linux box. It doesn't really look like there's a good solution for IE.

Here's what I tested now:

  • ajax calls wont work due to the same origin policy.
  • popups wont work because the parent can't control the child's DOM.
  • I tried an elaborate solution with popups where the child tries to control the parent, but once the parent is directed to the special protocol link the child has no more control over the opener.
  • protocolLong is an attribute of anchors, but it seems to only work for well-known protocols, not custom ones.
  • msLaunchUri doesn't work for IE<10
  • navigator.registerProtocolHandler seemed like a cool potential option to set the page where you can download the protocol to be a handler (and if you can already handle it, that option will appear on the top of the list), but it doesn't work in IE of course.

It seems the only solution is for IE users to just live with having two buttons, or to modify the user agent when installing the protocol.
Here's the two button solution:

<!doctype html>
<html lang="en">
<head></head>
<body>
<a id='installLink' href='http://www.whatever.com/getProtocol' style='display:none'>Don't already have the Test Application? Get it here</a>
<a id='launchLink' href="#" onclick="startProtocol()">Launch The Test Application</a>
<script>
var link = "testprotocol://dosomething?param1=true"; 
function startProtocol(){
  ifrm = document.createElement("iframe");
  ifrm.setAttribute("src", link);
  ifrm.style.display = "none";
  ifrm.onerror = getProtocol;
  document.body.appendChild(ifrm); 
}
function ieLaunch(){    
  document.getElementById('installLink').style.display='block';
  document.getElementById('launchLink').href = link;
}
function getProtocol(){ 
  if(confirm('You do not seem to have the TestProtocol installed, do you want to go download it now?')){
    document.location = 'http://www.whatever.com/getProtocol';
  }   
}
var ua = navigator.userAgent.toLowerCase();
if(ua.search("msie") !== -1 || ua.search("trident") !== -1) ieLaunch();
</script>
</body>
</html>

i537.photobucket.com/albums/ff338/ynori77/archenemysig1.jpg