2013-11-26 102 views
0

我在UIWebView中運行腳本,該腳本將數據發送回宿主應用程序(在Objective-C中)。如果我在指向myprotocol://some_data的頁面上放置鏈接,我會收到主機端的信息。在Javascript中調用自定義協議

如何在純Javascript中實現相同的行爲,而無需用戶交互?就像一個AJAX調用,但不是通過HTTP?

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

+0

查看答案http://stackoverflow.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

回答

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

+0

嗯 - 我沒有建議手動觸發click(),因爲我認爲這不會工作 - 很好的一個:) – Graham

1

好吧,我在Cordova的內臟裏挖了一下,好像他們爲此使用了iframe橋。從本質上講,他們動態創建一個iframe(因此iframe域與調用頁面相同),然後將iframe src更新爲自定義協議URL。

有趣的是iframe橋是iOS4的後備模式;他們確實使用XMLHttpRequest,但我還不確定他們如何解決同域策略。

編輯:要做到這一點,他們註冊一個自定義NSURLProtocol,然後發出一個HEAD請求以及所需的數據。

如果您想近距離觀察,請搜索Cordova附帶的cordova-js.zip文件中的exec.js文件。您可以在cordova-ios.zip內找到CDVURLProtocol.m的自定義協議。

+0

謝謝。我終於決定使用一個更簡單的解決方法,但是看看源代碼是什麼指向了正確的方向。我更容易實現,但仍幫助我!謝謝 –