但實際上 WKWebView 是一個多進程組件,Network Loading 以及 UI Rendering 在其它進程中執行。
因為WKWebView
屬於webkit
框架,因此WKWebView
的網絡請求、內容加載/渲染都是在WK Process
中進行,但NSURLProtocol
攔截請求還在App Process
,一旦注冊http(s) scheme
后,網絡請求將從獨立進程中發送到App Process
,這樣自定義的NSURLProtocol
才能攔截到網絡請求,為了提升進程間通信效率,出於性能上的考慮,Apple
會將request
的body
數據丟棄,因為body
數據(二進制類型)大小沒有限制,size
偏大的話就會對數據傳輸效率有嚴重影響進而影響到攔截請求時的操作及延時后續的網絡請求,因此,Apple
在進行進程間通信時會把post
請求的body
丟棄。
由於 WKWebView 在獨立進程里執行網絡請求。一旦注冊 http(s) scheme 后,網絡請求將從 Network Process 發送到 App Process,這樣 NSURLProtocol 才能攔截網絡請求。在 webkit2 的設計里使用 MessageQueue 進行進程之間的通信,Network Process 會將請求 encode 成一個 Message,然后通過 IPC 發送給 App Process。出於性能的原因,encode 的時候 HTTPBody 和 HTTPBodyStream 這兩個字段被丟棄掉了
參考蘋果源碼:
及bug report:
https://bugs.webkit.org/show_bug.cgi?id=138169(復制鏈接到瀏覽器中打開)
因此,如果通過 registerSchemeForCustomProtocol 注冊了 http(s) scheme, 那么由 WKWebView 發起的所有 http(s)請求都會通過 IPC 傳給主進程 NSURLProtocol 處理,導致 post 請求 body 被清空;
作者:Aiana
鏈接:https://www.jianshu.com/p/2339af964e73
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。