iOS WebViewブロックAjax要求

3193 ワード

title:iOS WebViewブロックAjax要求date:2016-04-12 00:08 tags:[iOS、Ajax、WebView]desc:iOS WebViewでjsブロックAjax要求を注入する.
iOSブロックWebView Request要求
みんながよく知らないと信じています.これはWebView delegateに実装されています.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    request = [IBWebMethod formAuthorizationRequest:request];
    return [IBWebMethod interceptRequest:request BaseViewController:self];
}
ture or falseは、WebViewが要求をロードするかどうかを決定する.new NSURLRequestによって元のrequestにカスタム情報(ヘッダまたはパラメータ)を追加できます.
しかし、Ajax要求はWebView全体を更新しないため、上記の方法では捕獲できない.
そこで、jsを注入してAjaxをポップアウトすることで捕獲することを考えました.StockOverFlowリンク
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='';
    this.setCoustomHeader();
    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;
}
XMLHttpRequest(Ajax)を書き換えたopenとsend方法でポップアウトイベントがキャプチャされたイベントの中でwindow.locationを再指定してWebViewのdelegateに応答することができます.
しかし、これはまだ私の需要を満たすことができません.Ajax要求はすでに出しました.私たちはAjax要求に頭を入れる必要があります.
コードを付ける
+ (NSString *)jsString:(NSString *)baseString{
    return [NSString stringWithFormat:@"%@
XMLHttpRequest.prototype.setCoustomHeader = function(){ this.setRequestHeader(\"Authorization\",\"%@\");}", baseString, [IBDataManager sharedManager].baseAuth]; }
同様にjs注入を利用して私達の頭を加入するAjax要求の中でAjaxカスタムheaderと捕獲の需要を達成しました.
iOS UICWebViewは大きな性能とメモリ漏れの問題があるので、UICWebViewとWKWebViewをパッケージ化してAPIとして起動することが考えられます.
最近は新しい需要と再構築コードを開発しています.この再構成はWebViewを単独で持ち出してBaseWebView Controllerを作っています.次のステップのためにUICWebViewとWKWebViewを統一して準備しています.
頑張ってください.