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

1 篇文章 0 订阅

 

在WebKit渲染页面前,首先要从网络加载主页面和所有的子资源数据,本文描述主页面资源加载过程中Get请求发送过程。

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

 

图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/

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值