Qt-Function-QWebFrame->load()_01
来源:互联网 发布:百度域名被劫持 编辑:程序博客网 时间:2024/06/16 01:20
前面只发布了QWebView的代码,并没有具体的解释过load()函数。在这里补充上。
2012.10.19 于济南
先贴上两个load的源码,分别命名为load1、load2,方便下文论述:
load1:
void QWebFrame::load(const QUrl &url){ // The load() overload ensures that the url is absolute. load(QNetworkRequest(url));}
load2:
void QWebFrame::load(const QNetworkRequest &req, QNetworkAccessManager::Operation operation, const QByteArray &body){ if (d->parentFrame()) d->page->d->insideOpenCall = true; QUrl url = ensureAbsoluteUrl(req.url()); WebCore::ResourceRequest request(url); switch (operation) { case QNetworkAccessManager::HeadOperation: request.setHTTPMethod("HEAD"); break; case QNetworkAccessManager::GetOperation: request.setHTTPMethod("GET"); break; case QNetworkAccessManager::PutOperation: request.setHTTPMethod("PUT"); break; case QNetworkAccessManager::PostOperation: request.setHTTPMethod("POST"); break; case QNetworkAccessManager::DeleteOperation: request.setHTTPMethod("DELETE"); break; case QNetworkAccessManager::CustomOperation: request.setHTTPMethod(req.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray().constData()); break; case QNetworkAccessManager::UnknownOperation: // eh? break; } QVariant cacheLoad = req.attribute(QNetworkRequest::CacheLoadControlAttribute); if (cacheLoad.isValid()) { bool ok; uint cacheLoadValue = cacheLoad.toUInt(&ok); if (ok) request.setCachePolicy(cacheLoadControlToCachePolicy(cacheLoadValue)); } QList<QByteArray> httpHeaders = req.rawHeaderList(); for (int i = 0; i < httpHeaders.size(); ++i) { const QByteArray &headerName = httpHeaders.at(i); request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName))); } if (!body.isEmpty()) request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size())); d->frame->loader()->load(request, false); if (d->parentFrame()) d->page->d->insideOpenCall = false;}
先看load1的内容。入口形参为const QUrl url,对于形参使用const定义,是为了在程序中不修改此形参的值,只使用此值,简单的说,这种形参就是输入参数,运行完此段程序,此形参的值并不发生变化。那么使用此url做了些什么呢?可以看到此函数只有一行,load(QNetworkRequest (url));,调用了此类(QWebFrame)中的一个load()函数。在C++中,可以根据入口形参类型及个数等自动匹配重载函数。那么我们需要知道这个入口形参的类型是否跟下面的load2的形参类型相同,也就是:这个load()是否就是调用的下文形参较多的那个load()。
为了查找实参类型,我们需要找到QNetworkRequest,位于src/network/access/目录中,qnetworkrequest.cpp。
QNetworkRequest::QNetworkRequest(const QUrl &url) : d(new QNetworkRequestPrivate){ d->url = url;}QNetworkRequest::QNetworkRequest(const QNetworkRequest &other) : d(other.d){}
可以看到,类QNetworkRequest有两个构造函数,重载了。对应于我们调用的这个,匹配的是第一种,入口形参为url的那个。
我们看到,第一个构造函数,自带初始化d = new QNetworkRequestPrivate。类QNetworkRequestPrivate是类QNetworkRequest的友元类,位于此cpp文件的上方,类的构造函数的定义放在了类的声明内部,看起来比较长。而d就是此类的一个实例,通过d的初始化可以看出来,也可以去qnetworkrequest_p.h中去看。此类中就定义了一个QUrl类型的url变量。所以就有了上述d->url = url;语句。
上面寻找qnetworkrequest的步骤比较多余。。。
我们知道,构造函数是没有返回类型的,那么通过构造函数,运行出来的是什么呢?其实对于load1,我们可以这样写:
QNetworkRequest *myInstance;myInstance = new QNetworkRequest(url);load(myInstance);
看出来了吧,构造函数运行出来的,就是这个类的实例,只不过没有具体的名字而已。通过这里,我们就可以看出了,load1的入口形参就是一个类型为QNetworkRequest的变量,正好对应于load2的第一个形参类型。我们知道,在C++中,实参的个数可以少于形参,前提是多出来的形参有默认的赋值,我们来看一下load2的声明:
void load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray());
可以看到,除了第一个参数外,后面两个形参均已经赋了默认值,这样在调用的时候,后两个参数就可以省略不写了,符合C++的语法规范。
从上面的叙述中,我们就可以确定,load1中调用的load(),就是load2。下面我们只要分析load2就行了。
函数一开始,又出现了d,综合多个类(像QWebFrame、QWebPage、QNetworkRequest等)来看,d是每个类友元类(类名+Private)的实例,仅限类内部调用,私有,不是全局变量。例如在类QWebFrame中,调用QWebPagePrivate的d,需要:d->page->d->...,其中page是QWebFrame中的成员变量,类型为QWebPage。关于这里出现的if操作,就先跳过了。
语句:QUrl url = ensureAbsoluteUrl(req.url());
先看这个函数ensureAbsoluteUrl(),字面意思可以看出:确保绝对Url。这需要先了解一下http协议的知识。http/1.1 中规定,浏览器所请求资源(URL)的确定可以有四种方式,其中一种就是由Request-URI直接确定,叫做绝对URI。看看这两者之间是否有联系。F2找到函数定义:
static inline QUrl ensureAbsoluteUrl(const QUrl &url){ if (!url.isValid() || !url.isRelative()) return url; // This contains the URL with absolute path but without // the query and the fragment part. QUrl baseUrl = QUrl::fromLocalFile(QFileInfo(url.toLocalFile()).absoluteFilePath()); // The path is removed so the query and the fragment parts are there. QString pathRemoved = url.toString(QUrl::RemovePath); QUrl toResolve(pathRemoved); return baseUrl.resolved(toResolve);}
这个函数的作用是:如果url不是relative的(relative就是没有http://的网址),则返回此url;换句话说,如果url是绝对的(absolute),则不对此url做其他操作,直接返回此url。至于valid与下面的其他操作暂时先不讨论,目测就是没有http时就给加上。
再看load2的下一条语句:
WebCore::ResourceRequest request(url);
需要找到这个类,位置:src\3rdparty\webkit\Source\WebCore\platform\network\qt\ResourceRequest.h。
- Qt-Function-QWebFrame->load()_01
- Qt-Function-QWebFrame->load()_02
- Qt-Function-QWebFrame->load()_03
- Qt-Function-QWebFrame->load()_04
- Qt-Function-QWebFrame->load()_05
- Qt-qwebframe-load()
- QT——QWebView、QWebPage和QWebFrame之间关系
- 从QWebView.load()(QWebFrame.load())切换到QNetworkAccessManager引起的CSS加载不了的问题记录
- 对比一下$(function () {});和$(window).load(function(){});
- $(window).on("load",function(){}和$(function(){})区别
- $(document).ready(function(){ ... })与$(window).load(function() { }
- $(window).on("load",function(){}和$(function(){})区别
- unable to load function FT_getDeviceInfo
- $(document).ready(){}),$(function(){}),$(window).load()
- Qt load image
- Qt image load path
- load() Function for PHP - Fetch URL Content
- $(window).load(function() {})和$(document).ready(function(){})的区别
- Web系统开发学习
- Open vSwitch 安装
- Eclipse3.2.1下的RCP程序,Export到Solaris motif解决办法
- 开发人员需要熟知的常用Linux命令(上)
- PO BO VO DTO POJO DAO概念及其作用
- Qt-Function-QWebFrame->load()_01
- 开发人员需要熟知的常用Linux命令-下
- 浅谈HTTP Adaptive Streaming技术及其前景
- iOS 6版本与之前版本差异总结
- ACRA(异常处理)
- Javascript学习路上--什么是cookie?
- (转)AspNetPager使用方法
- 程序员职业规划
- 【地球人..学习cocos2d-x】学习实践之逐步变强的HelloWorld(下集)