我正在UIWebView中运行一个脚本,该脚本将数据发送回主机应用程序(在Objective-C中)。如果我在页面上指向myprotocol://some_data
的链接,我会收到主机端的信息。
如何在没有用户交互的情况下在纯Javascript中实现相同的行为?类似于AJAX调用,但不是通过HTTP?
我正在使用AngularJS,但欢迎使用Javascript中的任何解决方案。
答案 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
的调用。