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/
分析的源码基于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/
相关文章推荐
- 从地址栏输入URL到页面加载显示的过程分析
- Webkit初始化以及加载URL过程中各种对象的建立时序以及DOM树的建立详情分析
- 页面加载时同时向两个不同的路径发送ajax请求,笨方法解决
- 前端webview,页面加载,发送Ajax请求,请求失败,https,http
- Chromium扩展(Extension)的页面(Page)加载过程分析
- webkit 加载plugin的过程分析(原)
- 在浏览器打开网站地址到回车发送请求到看到页面的过程
- asp.net中webservice请求发送原理和过程的初步分析[原]
- jqury+ajax每秒向后台发送请求数据然后返回页面(包括jqruy页面加载完毕才执行方法)
- 使用Fragment+ViewPager使用过程中禁止预加载未展示Fragment页面的网络请求
- HTML页面加载和请求发送时LOADING动画
- 身份验证拦截,Ajax请求跨域重定向到页面后不加载,场景分析
- Webkit分析传入的url到真正网络模块发起加载请求
- 浏览器发送一个请求到返回一个页面的具体过程
- 解决使用easyui的datagrid组件页面加载后发送两次请求的问题
- Fragment延迟加载数据,当页面可见时再发送请求
- Volly 发送网络请求过程分析
- 对于HTML页面中CSS, JS, HTML的加载与执行过程的简单分析
- URL页面请求过程分析
- Phantomjs 抓取、分析某个页面加载时浏览器发起的所有的子请求