mPaas-WKWebview网络拦截常见问题
1. 背景
原生WKWebView在獨立于app進程之外的進程中執行網絡請求,請求數據不經過主進程,因此在 WKWebView 上直接使用NSURLProtocol 是無法攔截請求的。但是由于mPaas的離線包機制強依賴網絡攔截,所以基于此,mPaas利用了WKWebview的隱藏api,去注冊攔截網絡請求去滿足離線包的業務場景需求,參考代碼如下:
[WKBrowsingContextController registerSchemeForCustomProtocol:@"https"]但是因為出于性能的原因,WK的網絡請求在給主進程傳遞數據的時候會把請求的body去掉,導致攔截后請求的body參數丟失。在離線包場景,由于頁面的資源不需要body數據,所以離線包可以正常使用不受影響。但是在H5頁面內的其他post請求會丟失data參數。為了解決post參數丟失的問題,mPaas通過在js注入代碼,hook了js上下文里的XMLHTTPRequest對象解決。通過在JS層把方法內容組裝好,然后通過WKWebView的messageHandler機制把內容傳到主進程,把對應HTTPBody然后存起來,隨后通知JS端繼續這個請求,網絡請求到主進程后,在將post請求對應的HttpBody添加上,這樣就完成了一次post請求的處理。整體流程可以參考之前崔同學的分享流程圖如下:
圖1
2. 遇到的問題
通過上面的機制,既滿足了離線包的資源攔截訴求,也解決了post請求body丟失的問題。但是在一些場景還是存在一些問題,需要開發者進行適配。
2.1. mPaas容器和三方容器混用導致三方容器請求body丟失
2.1.1. 問題場景
典型的場景,是在App內同時集成了多個wkwebview容器,常見的問題現象如下:打開mPaas容器后在打開三方的WK頁面,三方WK頁面內的post請求body參數丟失。原因是因為mPaas容器注冊了全局的網絡攔截,導致三方容器內的請求,也走到了mPaas的網絡攔截,但是因為mPaas容器沒有啟動,所以無法正常走到mPaas全局攔截補全body的鏈路,導致body參數丟失。
2.1.2. 解決方案
在三方容器創建的時候反注冊,在銷毀的時候再注冊回來。
j//反注冊 Class cls = NSClassFromString(@"WKBrowsingContextController");SEL sel = NSSelectorFromString([NSString stringWithFormat:@"unregisterSchemeForCustomProtocol:"]);if ([(id)cls respondsToSelector:sel]) {[(id)cls performSelector:sel withObject:@"http"];[(id)cls performSelector:sel withObject:@"https"];}//注冊Class cls = NSClassFromString(@"WKBrowsingContextController");SEL sel = NSSelectorFromString([NSString stringWithFormat:@"registerSchemeForCustomProtocol:"]);if ([(id)cls respondsToSelector:sel]) {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"[(id)cls performSelector:sel withObject:@"http"];[(id)cls performSelector:sel withObject:@"https"];#pragma}2.2. mPaas容器打開離線包后直接訪問虛擬域名導致白屏
2.2.1. 問題場景
和上面第一個case類似,也是在App內同時集成了多個wkwebview容器,同時三方的容器也會操作全局的網絡攔截,導致mPaas的網絡攔截失效。常見的問題現象如下:打開三方容器后,在打開mPaas的離線包后,發現離線包會直接通過在線網絡訪問虛擬域名,不走離線,導致頁面白屏。
2.2.1. 解決方案
參考第一個問題的解決方案,在啟動mPaas容器的時候,確認全局的網絡攔截是可以正常生效的就可以。
2.3. mPaas容器內sendBeacn請求body丟失
2.3.1. 問題場景
有客戶在容器內集成了神策的埋點jssdk,發現埋點請求里的body參數丟失。通過查看源碼發現神策jssdk是通過navigator.sendBeacon發送的請求,目前mPaas內hook的js請求,只支持XMLHTTPRequest,sendBeacon還不支持,所以導致走了網絡攔截后body參數丟失。
圖2
2.3.1. 解決方案
神策sdk內支持指定ajax的方式上報埋點,修改上報方式為ajax后問題解決。可參考文后資料[1]了解詳情。
圖3
[1]JavaScript SDK 使用說明:https://www.sensorsdata.cn/2.0/manual/js_sdk.html
我們是阿里云智能全球技術服務-SRE團隊,我們致力成為一個以技術為基礎、面向服務、保障業務系統高可用的工程師團隊;提供專業、體系化的SRE服務,幫助廣大客戶更好地使用云、基于云構建更加穩定可靠的業務系統,提升業務穩定性。我們期望能夠分享更多幫助企業客戶上云、用好云,讓客戶云上業務運行更加穩定可靠的技術,您可用釘釘掃描下方二維碼,加入阿里云SRE技術學院釘釘圈子,和更多云上人交流關于云平臺的那些事。
原文鏈接:https://developer.aliyun.com/article/784303?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的mPaas-WKWebview网络拦截常见问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 零起点入门教程:用宜搭简单布局一个首页
- 下一篇: 上海市新能源汽车数据平台引入阿里云Lin