2015-10-02 41 views
4

我有一個混合應用程序,它使用UIWebView從服務器加載ajax /多步驟表單。每個步驟都會向服務器發送ajax請求,並根據前面的步驟輸入從服務器接收適當的響應。在最後一步中,我希望能夠處理響應並在我的應用中使用這些信息來處理各種問題。使用Swift,實現這個目標的最好方法是什麼?我明顯可以在使用NSURLCache加載頁面時獲得初始響應,但我似乎無法弄清楚如何獲取在Ajax步驟之間正在接收的響應。有任何想法嗎?如何從UIWebView中的最終表單步驟獲取/處理ajax響應?

回答

1

正如你可以將自己的Javascript注入到UIWebView網頁中,一旦加載了初始頁面,就可以爲Ajax調用引入一個填充層。

在此墊片中,您可以加載一個構成的URL,您可以在UIWebView委託中根據Ajax調用檢測到該URL。當委託人看到假的URL時,您將記錄Ajax調用,但返回該負載不應發生。然後你可以調用原始的Ajax代碼,所以一切正常。

因此,雖然您無法檢測到Ajax調用,但您可以檢測URL請求。

以下的答案似乎有所有你需要:UIWebViewDelegate not monitoring XMLHttpRequest?

** **更新

我把代碼從上面的鏈接,並延長它還能檢測的響應。此更新後的代碼請求在'//'後加載包含readyState和http狀態的僞造URL。它在每一個準備好的狀態改變上都這樣做

所以,當一個Ajax請求時,你會看到你的UIWebView委託下列要求:

1)請求加載形式mpAjaxHandler的URL:// URL

2)在每個(),請求加載一個形式爲mpAjaxHandlerDone的URL:// readyState:httpstatus/URL

我想你正在尋找何時readyState變爲4,HTTP狀態爲200以獲得成功。

要激活此功能,請在主頁面在UIWebView中加載完成後加載下面的javascript,並查看您的委託是否觸發了請求和響應。

var s_ajaxListener = new Object(); 
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open; 
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send; 
s_ajaxListener.callback = function() { 
    console.log('mpAjaxHandler://' + this.url); 
    window.location='mpAjaxHandler://' + this.url; 
}; 
s_ajaxListener.callbackDone = function (state,status) { 
    console.log('mpAjaxHandlerDone://' + state + ':' + status + '/' + this.url); 
    window.location='mpAjaxHandlerDone://' + state + ':' + status + '/' + this.url; 
}; 

// Added this function to catch the readyState changes and request 
// fake page loads. 
function override_onreadystatechange(){ 
    s_ajaxListener.callbackDone(this.readyState); 
    this.original_onreadystatechange(); 
} 

XMLHttpRequest.prototype.open = function(a,b) { 
    if (!a) var a=''; 
    if (!b) var b=''; 
    s_ajaxListener.tempOpen.apply(this, arguments); 
    s_ajaxListener.method = a; 
    s_ajaxListener.url = b; 
    if (a.toLowerCase() == 'get') { 
    s_ajaxListener.data = b.split('?'); 
    s_ajaxListener.data = s_ajaxListener.data[1]; 
    } 
} 

XMLHttpRequest.prototype.send = function(a,b) { 
    if (!a) var a=''; 
    if (!b) var b=''; 
    s_ajaxListener.tempSend.apply(this, arguments); 
    if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a; 
    s_ajaxListener.callback(); 

    // Added this to intercept Ajax responses for a given send(). 
    this.original_onreadystatechange = this.onreadystatechange; 
    this.onreadystatechange = override_onreadystatechange; 
} 

我已經將代碼粘貼到這個W3Schools的演示的loadDoc()方法的頂部,並期待在JavaScript控制檯在瀏覽器中嘗試過這一點。 http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_first。如果您首先嚐試這兩個window.location=行註釋。

希望這可以幫助你,或給你一個開始。

+0

這似乎是一個攔截請求的可行選項,但我不明白這將如何幫助我處理來自服務器的響應。我沒有看到任何可以從服務器收到響應的墊片......我需要知道響應是成功的,以便我可以將某些返回數據存儲在我的應用中。 – kevindeleon

+0

我想在shim中,你可以用一個類似的技巧替換調用XMLHttpRequest的'onreadystatechange'函數。讓它檢查'readyState'並在每個狀態改變時加載假的URL,然後調用原始函數。這將是XMLHttpRequest的每個實例,而不是原型。 –

+0

@kevindeleon用擴展的javascript更新了答案,希望能夠滿足您的需求。 –