simplest cross-browser check if protocol handler is registered
Asked Answered
I

6

43

When user clicks link with custom protocol (like myapp://superlink)

I need either launch an app or allow user to download and run configuration app

I am looking for cross-browser way to check if custom protocol is registered

I've tried to determine this by checking user agent server-side (for IE)

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform] "myapp"=""

sends

`....NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3; **myapp**`

as user-agent

This is good, clean way, easy configuration:

just download .reg file and run it or propagiate via ms windows policy

I can't fix this for Chrome and Firefox

Are there any client-side solution (in js)?

My enviroment: IE8+, Chrome (latest), Firefox(latest)

Inhale answered 16/7, 2014 at 11:13 Comment(5)
What happens if you send an AJAX request using the sample protocol and then test the response?Max
@LeeTaylor - that won't work. CORS issues will kick in. Maybe this might help #837277Sunshade
if (!navigator.isProtocolHandlerRegistered("myapp", url)) { navigator.registerProtocolHandler("myapp", url, "Fake Protocol"); }Taitaichung
Hi! This super link actually starts our binary application (.exe) on client side or downloads installer, therefore no ajax can be usedInhale
I initially used habsq's code but it fails on some IE version then I tried gist.github.com/aaronk6/d801d750f14ac31845e8 and it works!Radom
B
30

There is this old tricks that it always never fails me.

The core functionality that you need is setTimeout. I will tell you in detail:

setTimeout(function() {
  window.location = "http://itunes.com/app/yourapplocation";
}, 200);

// once you do the custom-uri, it should properly execute the handler, otherwise, the settimeout that you set before will kick in
window.location = "myapp://superlink";

Now you mentioned that it maybe a link or links so I made this nice function just for your convenience:

HTML code

<a href="myapp://superlink" data-href-alt="http://itunes.com/app/yourapplocation">Click here</a>

JS code

$("a[href*='myapp://']").click(function(e)
{
  var el = $(this);
  setTimeout(function() {
    window.location = el.data("data-href-alt");
  }, 200);

  // once you do the custom-uri, it should properly execute the handler, otherwise, the settimeout that you set before will kick in
  window.location = el.data("href");

  e.preventDefault();
});

Hope this will help you :)

Brasilein answered 29/8, 2014 at 2:21 Comment(5)
I really like your jQuery code thats a nice and simple fix it might be worth bundling that into a plugin for jQuery sure loads of people would like to use that.Moderator
Hi! This super link actually starts our binary application (.exe) on client side or downloads installer, therefore no ajax can be usedInhale
This solution doesn't work for me. It opens the href and the alt-href. I would show you with a jsFiddle, but it doesn't like it when you set window.locationEarthiness
Seems to fail now on windows 10 build 1903Deciliter
Firefox now shows a popup asking for permission to open the custom protocol. So this redirects to the fallback URL anyway.April
M
20

I had a similar problem where I needed to check whether a custom protocol is already registered (which will open an executable file), or otherwise open a download page or do something else. Unfortunately there is no easy way to deal with this since every browser behaves differently. I tried to collect all information and come up with a rather generic library for this matter, you can take a look at:

https://github.com/ismailhabib/custom-protocol-detection

ps: the solution for non Windows 8 IE is rather ugly, but I couldn't find a better solution.

Miyokomizar answered 11/3, 2015 at 20:31 Comment(3)
So far on the browsers I have tested, this seems to work really well. Great work!Opia
Loved It Thank You So Much. Excellent Solution!Swinford
I am trying same library but it is not working for me. onBlur never triggers in any scenario whatever URI load successfully or failed. var timeout = setTimeout this function always triggers. Any idea if you faced?Wallace
E
10

kororo's solution wouldn't work for me for some reason, so I managed with this slightly modified solution instead.

<html>
<a id="link">Click Me</a>
<script>
var link = document.getElementById('link');
var timeout;
window.addEventListener('blur',function(e){
    window.clearTimeout(timeout);
})

link.addEventListener('click', function(e) { 

    timeout = window.setTimeout(function() {
      console.log('timeout');
      window.location = "https://myapp.net";
    }, 1000);

    window.location = "myapp://";
    e.preventDefault();
});
</script>
</html>
Earthiness answered 2/9, 2015 at 16:40 Comment(0)
A
8

Note that as at February 2020, there doesn't seem to be a working way to do this. Only considering Chrome, neither the solution from @kororo or @habsq work at the moment. The reason is that what we're trying to achieve by checking if a URL protocol handler exists is actually considered as being a security risk by some people.

So my advice is to not persevere in trying to get this to work.

The best case scenario if you try to get this work is that you succeed until some browser removes the mechanism which let you "hack" your way into checking the url protocol, and then you're back to square one again.

An easier way here is to do what even very large sites do, and have javascript on your page saying something like:

window.location = "myprotocol://asdf";

which will either work or not, and then displaying a message on the page saying something along the lines of "if this didn't work, then please download our software at such and such a link"

Aerothermodynamics answered 14/2, 2021 at 23:21 Comment(3)
another thing to add on: have a callback system with a unique browser id on the application to tell the server that the protocol got triggered so it doesn't need to show the download promptDorindadorine
@Yakov.P yeah, I thought this way too, but there are a couple of difficulties here, which prevent this from being a really good idea in my opinion. 1. If someone misses the download prompt the first time, then they won't have a way to install the program next time. 2. If someone uses a different browser, then this check will fail anyway. 3. If someone downloads the tool and uninstalls it, they won't have a way to reinstall againAerothermodynamics
It can check each time, it doesn't need to be one-time then never prompt again. (if the program is uninstalled, it won't run and it won't give the server a greenlight and thus, yielding another prompt)Dorindadorine
K
2

Update to Korono's answer, this worked for me:

$(function() {
    var timeIndex;
    $("a[href*='myapp://']").blur(function(e)
    {
        clearTimeout(timeIndex);
    });

    $("a[href*='myapp://']").click(function(e)
    {
      var el = $(this);
      timeIndex = setTimeout(function() {
        window.location = el.attr("data-href-alt");
      }, 200);

      // once you do the custom-uri, it should properly execute the handler, otherwise, the settimeout that you set before will kick in
      window.location = el.attr("href");
      e.preventDefault();
    });
});
Kickshaw answered 12/10, 2017 at 20:37 Comment(0)
S
-1

Salaam

Install ismailhabib/custom-protocol-detection

By including this JS file protocolcheck.js

Then write code something like this

<div id="protocol" href="myprotocol:[email protected]">Check Protocol</div>

<script>
        $("#protocol").click(function (event) {
            protocolCheck($(this).attr("href"), function () {
                    alert("protocol not recognized");
                });
            event.preventDefault ? event.preventDefault() : event.returnValue = false;
        });
</script>
Swinford answered 21/6, 2019 at 5:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.