您的位置:首页 > 其它

Webkit页面加载过程分析(1)-发送请求篇

2012-12-06 00:52 399 查看
在WebKit渲染页面前,首先要从网络加载主页面和所有的子资源数据,本文描述主页面资源加载过程中Get请求发送过程。

分析的源码基于Qt5beta2版本的WebKit



[align=left] [/align]

图1 WebCore页面加载图

1. 应用层处理过程

当用户输入URL网址回车后,应用外壳程序首先得到处理,BrowserMainWindow::loadUrl被调用,并进而间接调用WebView::loadUrl函数

WebView::loadUrl --> QWebView::load

这时即进入WebKit API层了,

2. WebKit API层处理过程

如上图1,QWebView::load函数中,Webview对象首先通过QWebPage对象得到QWebFrame对象,并调用load函数,进入通过内部关联的Frame对象获取到FrameLoader对象,从而调用WebCore的Loader模块处理入口FrameLoader::load,函数调用过程如下

--> QWebView::load

--> QWebFrame::load(url)

--> QWebFrame::load(QNetworkRequest(url) ... ) //此函数中初始化一个WebCore::ResourceRequest request(url);临时资源请求变量

--> FrameLoader::load // load 函数1

FrameLoader即使WebKit内核层代码了,即WebCore的Loader部分

3. WebCore处理过程

* 如图1,FrameLoader首先创建一个新的DocumentLoader对象,后续在FrameLoader::loadWithDocumentLoader将触发导航裁决,导航裁决通过后,FrameLoader::continueLoadAfterNavigationPolicy将被调用,即NavigationPolicy后的继续加载,continueLoadAfterNavigationPolicy将FrameLoader对象的状态转换为“FrameStateProvisional”,并在下一步的continueLoadAfterWillSubmitForm函数中调用DocumentLoader::startLoadingMainResource开始主资源加载。startLoadingMainResource中将创建MainResourceLoader对象。

--> FrameLoader::load // load 函数1

--> FrameLoader::load // oad函数2, 此处创建一个 DocumentLoader 对象

--> FrameLoader::load(newDocumentLoader) // load函数3,

-->FrameLoader::loadWithDocumentLoader

-->FrameLoader::setPolicyDocumentLoader(loader); // loader 即那个新DocumentLoader 对象, 担当PolicyDocumentLoader

-->PolicyChecker::checkNavigationPolicy // 导航裁决? 并传人回调函数callContinueLoadAfterNavigationPolicy

* 导航裁决后的处理FrameLoader::callContinueLoadAfterNavigationPolicy

-->FrameLoader::callContinueLoadAfterNavigationPolicy

-->FrameLoader::continueLoadAfterNavigationPolicy

-->FrameLoader::setProvisionalDocumentLoader(m_policyDocumentLoader.get()); // 那个新DocumentLoader对象又担当ProvisionalDocumentLoader

-->FrameLoader::setState(FrameStateProvisional); // 转变为FrameStateProvisional状态

-->FrameLoader::setPolicyDocumentLoader(0); // 清除PolicyDocumentLoader,以上3行完成状态切换

-->FrameLoader::continueLoadAfterWillSubmitForm

-->DocumentLoader::startLoadingMainResource() // m_provisionalDocumentLoader对象的成员函数

-->MainResourceLoader::create // 创建MainResourceLoader对象

-->MainResourceLoader::load

-->MainResourceLoader::loadNow

-->ResourceHandle::create

--> new ResourceHandle // 首先new一个新的ResourceHandle对象

-->ResourceHandle::start // QT版在文件ResourceHandleQt.cpp中, new 一个 QNetworkReplyHandler 对象

-->QNetworkReplyHandler::QNetworkReplyHandler // 构造函数,仍然是WebCore的platform中的对象,未进入QtNetwork

-->ResourceRequest::toNetworkRequest // 由 ResourceRequest 对象生成QNetworkRequest对象m_request

-->QNetworkReplyHandlerCallQueue::push // 将QNetworkReplyHandler::start函数push到队列m_queue,该函数随后将被调用

-->QNetworkReplyHandlerCallQueue::flush() // 处理队列中的call任务,将调用QNetworkReplyHandler::start

* QNetworkReplyHandler::start 函数分析

-->QNetworkReplyHandler::start

-->QNetworkReplyHandler::sendNetworkRequest

-->QNetworkAccessManager::get() [post/head/put/deleteResource/sendCustomRequest] // 调用QtNetwork服务异步发送网络请求,返回一个QNetworkReply对象reply

-->new QNetworkReplyWrapper(reply) // 生成了网络应答包装对象QNetworkReplyHandler::m_replyWrapper

* 发送信号后如何处理网络应答数据?

在QNetworkReplyWrapper::QNetworkReplyWrapper构造函数中,会将reply对象的Qt信号connect到QNetworkReplyWrapper的槽函数

connect(m_reply, SIGNAL(finished()), this, SLOT(setFinished()));

connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData()));

connect(m_reply, SIGNAL(readyRead()), this, SLOT(receiveMetaData()));

在这些槽函数中触发网络应答处理,具体细节本文不再描述,本文仅分析到网络请求发送。

初涉WebKit不久,有不正确的地方,欢迎评论纠正。

图片来源:https://www.webkit.org/blog/1188/how-webkit-loads-a-web-page/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: