WebKit Loader模块介绍
一.下面重點介紹一下與Loader相關的數據結構和模塊。
?
Frame:可以看做是瀏覽器外殼調用Loader的總入口,它就像我們印象中的一個網頁,它關注的是頁面的顯示?(FrameView)?、頁面數據的加載(FrameLoader)?、頁面內的各種控制器?(Editor, EventHandler, ScriptController, etc.)?等等,它包含以下模塊(只列出重點):
Document
Page
FrameView
RenderView
FrameLoader
DOMWindow
?
下面分別介紹(PS:?必須要了解這些概念,不然后面的東東都無法理解):
?
1)Document:這個類的爺爺類是?Node,它是?DOM?樹各元素的基類;?Document?有個子類是?HTMLDocument?,它是整個文檔?DOM?樹的根結點,這樣就明白了:原來?Document?就是描述具體文檔的代碼,看一下它的頭文件,就更明白了,它的屬性與方法就是圍繞著各種各樣的結點:?Text?,?Comment?,?CDATASection?,?Element……
?
2)Page:我的理解是,Page與Frame(嚴格說是FrameView)是一一對應的,Frame關注UI,Page關注數據。現在的瀏覽器一般都提供同時打開多個窗口,每一個窗口對應的數據就是這個Page在管理了。
??在?page.cpp?文件里,還有個重要的全局指針變量:?static HashSet<Page*>* allPages;?這個變量包含了所有的page實例。
?
3)FrameView:可以理解為為一個網頁的ViewPort,?它提供一個顯示區域,同時包含的有Render根節點、layout排版相關接口、Scroll相關等。?FrameView是Layout排版的總入口。
?
4)RenderView:與FrameView差不多,只是分工不同,它管理與Render樹相關的東東。
?
5)?FrameLoader:重點,FrameLoader類將Documents加載到Frames。當點擊一個鏈接時,FrameLoader創建一個新的處于“policy”狀態的DocumentLoader對象,一旦webkit指示FrameLoader將本次加載視為一個導航(navigation),FrameLoader就推動DocumentLoader進入“provisional”狀態,(在該狀態,DocumentLoader發調用CURL發起一個網絡請求,并等待是html還是下載文件。)同時,DocumentLoader會創建一個MainResourceLoader對象(該對象在后面單獨介紹)。
6)。DOMWindow:實現了Dom的一些接口,如CreateNode等。后面可以詳細講講。
?
上面介紹的概念比較多,我也不曉得好不好理解,沒理解也不怕,多去看看代碼,這是必須的。
?
另外看看下面的圖,就會清晰很多的
二、Webkit的Loader有兩條加載數據的主線:?(從上圖可以看到)
1. MainResourceLoader:該模塊主要加載主網頁請求。后面稱為MainResource。
2. DocLoader:該模塊除了主網頁外的所有子請求,如:.js文件,圖片資源,.css文件。??后面稱為SubResource。
?
MainResource部分:
FrameLoader->DocumentLoader->MainResourceLoader-ResourceHandleDocumentLoader經歷狀態:1)"policy" 2) "provisional" 3)"commited"分別是等待、作為navigation發送network request、文件下載完畢
?
Subresource部分:
DocLoader->Cache->[CacheObjects]example: CacheImage->SubresourceLoader->ResourceHandle?當請求一個資源時,首先查看Cache中是否存在該對象,如果存在直接返回;如果不存在,創建該Cache對象(如CacheImage),然后創建一個SubresourceLoader,加載資源。
舉例說明:
??加載圖片時,DocLoader首先詢問Cache,?在內存中是否也存在(CachedImage對象),如果已存在,則直接加載,即省了時間又省了流量。如果圖片不在Cache中,?Cache首先創建一個新的CachedImage對象來代表該圖片,然后由CachedImage對象調用Loader對象發起一個網絡請求,Loader對象創建SubResourceLoader。后面的流程就一樣了,SubResourceLoader也是直接把ResourceHandle打交道的。
?
接下來跟蹤一下Loader發送請求的代碼實現:
1.?用戶輸入URL后,最先調用的接口是:
FrameLoader::load(constResourceRequest& request)
?
ResourceRequest包含了:
KURL(處理url的一個類)、setHTTPHeaderField、setHTTPContentType等與HTTP頭部相關的函數
?
2.Load()通過ResourceRequest數據調用createDocumentLoader(request, substituteData)來創建一個DocumentLoader。
?
3.Load()函數繼續給request設置HttpAccept,Cache-Control HTTP頭等信息。
?
4.?設置FrameLoader::checkNavigationPolicy函數進入"Policy"狀態。
?
5.判斷該url是否在Cache中等一系列狀態判斷后,進入DocumentLoader::startLoadingMainResource函數準備加載MainResource。該函數首先會創建調用MainResourceLoader。
?
6.進入MainResourceLoader::load函數,調用illSendRequest(r,ResourceResponse());做發送請求前的準備。
?
7.調用PolicyCheck檢查policy的狀態后,進入FrameLoader::callContinueLoadAfterNavigationPolicy繼續往下走。
?
8:在MainResourceLoader::loadNow(ResourceRequest&r)函數里創建ResourceHandle,在創建ResourceHandle函數中,調用start函數,start函數把ResourceHandle自已添加到ResourceHandleManager的m_resourceHandleList隊列里。
??同時,調用m_downloadTimer.startOneShot激活網頁請求下載的定時器。(這是個毫秒級的定時器,采用定時器的原因也是為了實現異步的請法)
?
??可以看到m_downloadTimer的定義:Timer<ResourceHandleManager> m_downloadTimer;
? m_downloadTimer是實現的一個定時器模塊類,在它的構造函數里已經傳入了回調函數的地址:ResourceHandleManager::downloadTimerCallback。
?
9.?一路返回到Load()函數,并返回到調用源,函數執行完畢。
?
10.? ResourceHandleManager::downloadTimerCallback回調函數被定時器調用。
?
11.?可以看到downloadTimerCallback函數的代碼:
???????????調用libcurl庫的接口curl_multi_fdset,curl_multi_perform等查詢數據。
總結
以上是生活随笔為你收集整理的WebKit Loader模块介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Http响应码
- 下一篇: WebKit Page对象的分析