在Javascript中调用自定义协议

问题描述:

我在UIWebView中运行脚本,该脚本将数据发送回宿主应用程序(在Objective-C中)。如果我在指向myprotocol://some_data的页面上放置链接,我会收到主机端的信息。在Javascript中调用自定义协议

如何在纯Javascript中实现相同的行为,而无需用户交互?就像一个AJAX调用,但不是通过HTTP?

我使用的是AngularJS,但Javascript中的任何解决方案都是受欢迎的。

+0

查看答案http://*.com/questions/10167100/how-to-make-a-jquery-get-ajax-request-to-a-private-custom-url-protocol – Graham

+0

我看到了,但“你必须从头开始”并不是指向我的一些解决方案 –

+0

你不能做ajax请求,但你是否尝试过简单地做'window.location ='myprotocol://';'? – Graham

我发现没有办法做到这一点没有“作弊”在某种程度上。我决定在我的页面中创建一个<a>元素,并动态更改其href属性,然后使用Javascript触发其上的click事件。下面是我做的:

CSS

a#sendToiOS { 
    display:block; 
    position: fixed; 
    bottom: -1px; 
    right: -1px; 
    z-index: -1; 
    opacity: 0; 
    width: 1px; 
    height: 1px; 
} 

的Javascript

var sendToiOS = function(protocol, action, params) { 
    var e = document.createElement('a'); 
    e.id = 'sendToiOS'; 
    var strParams = ""; 
    if(typeof params !== 'undefined') { 
     Object.keys(params).forEach(function(key) { 
     strParams += strParams != "" ? '&' : ''; 
     strParams += key+'='+encodeURI(params[key]); 
     }); 
    } 
    e.href = strParams.length > 0 ? protocol+'://'+action+'?'+strParams : protocol+'://'+action; 
    document.getElementsByTagName('body')[0].appendChild(e); 
    e.click(); 
    e.parentNode.removeChild(e); 
    } 

调用然后sendToiOS('mycustomprotocol', 'some_action', {foo: 'bar', foo2: 1337});将触发调用mycustomprotocol://some_action?foo=bar&foo2=1337

+0

嗯 - 我没有建议手动触发click(),因为我认为这不会工作 - 很好的一个:) – Graham

好吧,我在Cordova的内脏里挖了一下,好像他们为此使用了iframe桥。从本质上讲,他们动态创建一个iframe(因此iframe域与调用页面相同),然后将iframe src更新为自定义协议URL。

有趣的是iframe桥是iOS4的后备模式;他们确实使用XMLHttpRequest,但我还不确定他们如何解决同域策略。

编辑:要做到这一点,他们注册一个自定义NSURLProtocol,然后发出一个HEAD请求以及所需的数据。

如果您想近距离观察,请搜索Cordova附带的cordova-js.zip文件中的exec.js文件。您可以在cordova-ios.zip内找到CDVURLProtocol.m的自定义协议。

+0

谢谢。我终于决定使用一个更简单的解决方法,但是看看源代码是什么指向了正确的方向。我更容易实现,但仍帮助我!谢谢 –