相信你們都不陌生,這個在WebView delegate裏有實現
貼一段代碼web
- (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來向request裏添加自定義的信息(頭或參數)
<!--more-->ajax
可是因爲Ajax 請求不是刷新整個WebView,上面的方法中沒法捕獲。app
因而就想到了想到了經過注入js來pop 出Ajax事件來捕獲。
StackOverFlow連接ide
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方法來pop出事件
在捕獲的事件中從新指定了window.location來響應WebView的delegatepost
上代碼性能
+ (NSString *)jsString:(NSString *)baseString{ return [NSString stringWithFormat:@"%@\n XMLHttpRequest.prototype.setCoustomHeader = function(){ this.setRequestHeader(\"Authorization\",\"%@\");}", baseString, [IBDataManager sharedManager].baseAuth]; }
一樣利用js注入把咱們的頭加入的Ajax請求中
達到了Ajax自定義header 與捕獲的需求ui
iOS UIWebView 有很大的性能和內存泄漏的問題
能夠考慮將UIWebView與WKWebView封裝成一套API來調用this
最近在開發新的需求和重構代碼,這段重構把WebView單獨拿出來作成了一個BaseWebViewController,爲下一步將UIWebView與WKWebView統一作準備。url