是否可以使用Google Chrome打开自定义网址方案?

时间:2010-02-24 23:43:56

标签: ajax macos google-chrome

我有协议(如http),其计划由在Mac OS X中注册的第三方应用程序管理。 即,x-someapp:// someaction或类似的东西。

如何使用Google Chrome打开此网址? 默认情况下,Chrome会开始在Google引擎中进行搜索,而不是启动应用并将URL处理传递给它...

Safari推出一些已注册的应用程序。这是对的。

Firefox和Opera询问该怎么做......我也可以启动App。

但Chrome ......不问。

我甚至尝试在里面写一些带有JavaScript的HTML页面来发送XHttpRequest:

function _httpExecuteCallback()
{
 if (httpRequestCallbackFunction != null) {
  if (httpRequest.readyState == 4) {
   if (httpRequest.status == 200) {
    httpRequestCallbackFunction();
    httpRequestCallbackFunction = null;
   }   
  }
 }
}

function _httpGet(url, callbackFunction)
{
 httpRequest = false;
 httpRequestCallbackFunction = callbackFunction;
 httpRequest = new XMLHttpRequest();
 httpRequest.onreadystatechange = _httpExecuteCallback;
 httpRequest.open('GET', url, true);
 httpRequest.send(null);
}


_httpGet('x-someapp://test',function(){})

也没有结果......

6 个答案:

答案 0 :(得分:24)

当前接受的解决方案存在Chrome for SSL https问题。观看控制台日志,Chrome会阻止请求,因为它认为自定义网址协议不安全:

[blocked] The page at reports blah blah ran insecure content from customproto//blah blah

这是一个解决方案(我花了几天时间研究):

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

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

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

此代码不适用于IE。我发现使用这种技术IE将自定义协议的参数限制为小于1000,因为使用iFrame技术IE将允许2083个字符。

克服javascript中url限制的唯一方法是查看数据并多次调用。如果有人想要捅这个,请告诉我它是怎么回事。我想用它。

要在执行的应用程序中处理长网址,请将一个标记传递到应用程序并让它从网址GET获取数据。

所以现在我正在使用Chrome / FF的一个功能和IE的另一个功能。

这些链接帮助我开发了这个解决方案:

https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

Simulating a click in jQuery/JavaScript on a link

(希望我前几天知道这件事......希望这有助于某人)

=============================================== ===

更新:(8小时后)

=============================================== ===

杰克为chrome发布了一个很棒的解决方案:https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

仅适用于chrome:

 window.location.assign("customprotocol://");

它会在iframe中失败,所以这是有效的:

var w = (window.parent)?window.parent:window
w.location.assign(service + '://' +  data)

=============================================== ===

更新:(几周后)

=============================================== ===

打开自定义协议的所有示例(包括我自己的协议)在网址中都有一个“://”。这就是造成SSL警告的原因。

原来解决方法是将“://”更改为“:”

这样做:

src="x-myproto:query"  .....

并且SSL警告将消失。

=============================================== ===

遵循:(经过数月的生产使用)

=============================================== ===

这对于chorme来说效果很好。检测浏览器以及chrome是否执行此操作:

var w = (window.parent)?window.parent:window
w.location.assign('myproto://xyzabcdefetc')

对于IE和其他浏览器,我做了一些略有不同的事情。

请注意,浏览器会限制您可以在自定义网址协议中放入多少数据。只要您的字符串不超过800个字符,这似乎是适用于所有浏览器的神奇数字。

答案 1 :(得分:7)

看起来Google的位置栏解析正在阻碍它。

然而,浏览器似乎确实正确处理了自定义URL方案。请在您的位置栏中尝试此操作:

javascript:document.location = 'myscheme://whatever'

您网页上使用自定义方案的任何链接也应该做正确的事情。

答案 2 :(得分:4)

这是一个解决方案,如果用户没有应用,还包括重定向到App Store / Play商店。它使用setTimeout。它还使用iframe来支持更多浏览器。因此,这适用于Chrome和任何其他移动浏览器。我们将此作为我的公司Branch使用。只需修改下面的两个链接即可对应您的URI和App Store链接。

<!DOCTYPE html>
<html>
    <body>
        <script type="text/javascript">
            window.onload = function() {
                // Deep link to your app goes here
                document.getElementById("l").src = "my_app://somepath";

                setTimeout(function() {
                    // Link to the App Store should go here -- only fires if deep link fails                
                    window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8";
                }, 500);
            };
        </script>
        <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
    </body>
</html>

同样,这可以在任何浏览器上运行,这要归功于iframe。

答案 3 :(得分:2)

如果Chrome无法识别网址方案,则默认为搜索。

这是我在Safari中看到的: alt text http://img62.imageshack.us/img62/6792/clipboard02oh.jpg

并在Firefox中:

alt text http://img138.imageshack.us/img138/9986/clipboard04xk.jpg

我认为Chrome默认搜索的原因是有特殊的谷歌搜索使用冒号。

E.g:

  • define:dictionary
  • filetype:pdf google chromium

这是我对Firefox的烦恼之一,我必须跳转到“搜索框”而不是地址栏来执行这些类型的搜索。由于Chrome没有像Firefox,IE和Safari这样的单独搜索框,因此需要此功能。

Ajax请求不会让你解决这个问题。

答案 4 :(得分:2)

我找到了适用于Chrome的解决方案。 我使用IFRAME方式。

示例(使用JQuery):

$("body").append('<span id="__protoProxy"></span>');

function queryWord(aWord)
{
 var protoProxy = document.getElementById('__protoProxy');
 if (protoProxy)
 {   
  var word = aWord.replace('"','\"');
  protoProxy.innerHTML = '<div style="display:none;"><iframe src="x-myproto://query?' + word + '"></iframe></div>';
 }
}

queryWord('hello');

答案 5 :(得分:0)

几周后....

window.location.replace('myscheme://whatever')一样,具有完整的跨浏览器支持,可与chrome,firefox,safari,edge,opera一起使用,请参见https://developer.mozilla.org/en-US/docs/Web/API/Location/replace