在Javascript中调用自定义协议

时间:2013-11-26 19:27:27

标签: javascript objective-c

我正在UIWebView中运行一个脚本,该脚本将数据发送回主机应用程序(在Objective-C中)。如果我在页面上指向myprotocol://some_data的链接,我会收到主机端的信息。

如何在没有用户交互的情况下在纯Javascript中实现相同的行为?类似于AJAX调用,但不是通过HTTP?

我正在使用AngularJS,但欢迎使用Javascript中的任何解决方案。

2 个答案:

答案 0 :(得分:1)

好吧,我在Cordova的内心深处挖掘,看起来他们使用的是iframe桥。基本上他们动态创建iframe(因此iframe域与调用页面相同),然后将iframe src更新为自定义协议URL。

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

编辑:要执行此操作,他们会注册自定义NSURLProtocol,然后发出HEAD请求以及所需数据。

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

答案 1 :(得分:1)

我发现如果不以某种方式“欺骗”,就没有办法做到这一点。我决定在我的页面中创建一个<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的调用。