Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I've successfully created and registered a custom protocol handler in my web application and it's working fine in all browsers. There's the initial warning dialog about launching an external application which is fine.

However when the app is deployed and the site is running under SSL, the custom protocol links no longer work in Chrome. I see the following message appears in the Developer Tools console:

[blocked] The page at https://my.site.com/path/to/page ran insecure content from iwd:-action=myaction

The same links work fine in Internet Explorer and Firefox.

Any ideas as to how to make this work? My external application by the way is a console application that's installed on the client.

edit: One extra important piece of information is that the link specifies a target which is a hidden iframe on the same page.

share|improve this question

4 Answers 4

up vote 2 down vote accepted

The solution was to not specify a target frame for Chrome users. It would appear that Chrome is looking at the url being passed from the main page to the embedded iframe and sees that the embedded iframe url is not secure and therefore rejecting it.

I don't think Chrome always behaved this way but with v30+ the solution appears to be to specify and empty target in the link.

Edit - expanded solution

Here's the JavaScript I use to clean the target attributes of the links (for Chrome users only) - Otherwise, the simple solution is to not specify a target attribute in the HTML in the first place.

// Get a list of all the links with external commands
var commandButtons = $("a[target='my_command']");
updateCommandButtonTargetsForChrome();

// Remove target attribute for Chrome only users
function updateCommandButtonTargetsForChrome() {
    var browserInfo = getBrowserInfo();
    if (browserInfo[0] == "Chrome")
        commandButtons.attr("target", "");
}

function getBrowserInfo() {
    var n = navigator.appName, ua = navigator.userAgent, tem;
    var m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
    if (m && (tem = ua.match(/version\/([\.\d]+)/i)) != null) m[2] = tem[1];
    m = m ? [m[1], m[2]] : [n, navigator.appVersion, '-?'];
    return m;
}
share|improve this answer
1  
Glad to see I'm not the only one to run into this very same issue. Doesn't it seem like a bug in Chrome v30 though? Unless there is some way for a custom protocol handler to be designed as "secure" then this breaks anything that uses a custom protocol handler in an iframe of a secure page. –  Ron Michael Zettlemoyer Oct 9 '13 at 14:24
    
Can you elaborate as to how you did this? I am having the same problem. –  Brian McGinity Oct 17 '13 at 8:08
    
@BrianMcGinity I've edited the answer to provide the javascript code –  Catch22 Oct 17 '13 at 11:34
    
Thank you, looks great. Do you have problems when the SRC of iframe is more than 2000 or so characters? I would like to pass 10k or more to a vbscript. When I pass lots of data, it just dies. –  Brian McGinity Oct 18 '13 at 1:15
    
I figured out 2083 is the documented max. Wonder if it possible for the executable to call a js function in the html page? –  Brian McGinity Oct 18 '13 at 2:19

Since it looks like all of the answers in this thread are already doing things specific to Chrome, there is a much simpler way to open an application via protocol handler that only will only work for Chrome.

Simply call window.location.assign("customprotocol://");. As far as the user is concerned, this will work exactly the same as the IFRAME approach used to. If the user does not have the protocol handler installed, nothing happens. If the protocol handler is installed, it will open the application.

This will only work in Chrome, as Firefox and IE will redirect the user to a "Could not load" page if they do not have the protocol handler installed on their machine.

share|improve this answer
1  
This is great!!!!! It works well. It fails in an iframe, so this fixes it: var w = (window.parent)?window.parent:window w.location.assign(service + '://' + data) –  Brian McGinity Oct 19 '13 at 3:00
    
formating is off in my comment above: var w = (window.parent)?window.parent:window; w.location.assign(service + '://' + data) –  Brian McGinity Oct 19 '13 at 3:09
    
I have referenced this thread at: stackoverflow.com/questions/2330545/… –  Brian McGinity Oct 19 '13 at 3:11

Thank you for finding this, using the same principle, I turned it into a dynamic function call, here's the code:

    <input type='button' value='Test Custom Url' onclick='exec()'>

    <script>
    function submitRequest(buttonId) {
        if (document.getElementById(buttonId) == null || document.getElementById(buttonId) == undefined) return;
        if (document.getElementById(buttonId).dispatchEvent) {
                var e = document.createEvent("MouseEvents");
                e.initEvent("click", true, true);
                document.getElementById(buttonId).dispatchEvent(e);
        } 
        else {
                document.getElementById(buttonId).click();
        }
    }

    function exec(){
        var f = document.getElementById('customUrlLink')
        if (f ) {f.parentNode.removeChild(f);}
        var a = document.createElement('a');
        a.href =  'mycustomproto://arg1';    
        a.innerHTML = "Link"                                    
        a.setAttribute('id',        'customUrlLink');
        a.setAttribute("style", "display:none; "); 
        document.body.appendChild(a); 
        submitRequest("customUrlLink");
    }
    </script>

One thing, this code will not run in an iframe. So the iframe can call this in the parent or it is possible to create the link object in the parent.

Also IE only allows <1000 (i don't know the exact number) characters using this approach.

share|improve this answer

It looks like the problem the whole time is how the url is written.

create the url without the "//":

customproto:xyzabcdef

Instead of:

customproto://xyzabcdef
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.