it-swarm-ja.com

カスタムプロトコルハンドラーがSSLページのChrome

Webアプリケーションでカスタムプロトコルハンドラーを正常に作成して登録しましたが、すべてのブラウザーで正常に機能しています。外部アプリケーションの起動に関する最初の警告ダイアログがありますが、これは問題ありません。

ただし、アプリがデプロイされ、サイトがSSLで実行されている場合、カスタムプロトコルリンクはChromeで機能しなくなります。開発者ツールコンソールに次のメッセージが表示されます。

[ブロック] https://my.site.com/path/to/page のページでiwdから安全でないコンテンツが実行されました:-action = myaction

同じリンクがInternetExplorerとFirefoxで正常に機能します。

これを機能させる方法について何かアイデアはありますか?ちなみに私の外部アプリケーションは、クライアントにインストールされているコンソールアプリケーションです。

edit:さらに重要な情報の1つは、リンクが同じページの非表示のiframeであるターゲットを指定していることです。

2
Catch22

解決策は、Chromeユーザーのターゲットフレームを指定しないことでした。Chromeは、メインページから埋め込みに渡されるURLを見ているように見えますiframeであり、埋め込まれたiframe URLが安全ではないため、拒否されていることがわかります。

Chromeが常にこのように動作するとは思いませんが、v30 +では、リンクでターゲットを指定して空にすることが解決策のようです。

編集-拡張ソリューション

リンクのターゲット属性をクリーンアップするために使用するJavaScriptは次のとおりです(Chromeユーザーのみ)-それ以外の場合、簡単な解決策は、最初からHTMLでターゲット属性を指定しないことです。

// 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;
}
2
Catch22

いつも問題はURLの書き方にあるようです。

「//」なしでURLを作成します。

customproto:xyzabcdef

の代わりに:

customproto://xyzabcdef
1
Brian McGinity

このスレッドのすべての回答はすでにChromeに固有のことを行っているように見えるため、Chromeでのみ機能するプロトコルハンドラーを介してアプリケーションを開くはるかに簡単な方法があります。

window.location.assign("customprotocol://");を呼び出すだけです。ユーザーに関する限り、これは以前のIFRAMEアプローチとまったく同じように機能します。ユーザーがプロトコルハンドラーをインストールしていない場合、何も起こりません。プロトコルハンドラーがインストールされている場合は、アプリケーションが開きます。

FirefoxとIEは、マシンにプロトコルハンドラーがインストールされていない場合、ユーザーを「読み込めませんでした」ページにリダイレクトするため、これはChromeでのみ機能します。

1
Jake Weber

これを見つけてくれてありがとう、同じ原理を使って、私はそれを動的関数呼び出しに変えました、ここにコードがあります:

    <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>

1つは、このコードはiframeでは実行されないということです。したがって、iframeはこれを親で呼び出すことができます。または、親でリンクオブジェクトを作成することもできます。

また、IEは、このアプローチを使用して<1000(正確な数はわかりません)文字のみを許可します。

0
Brian McGinity