QT(17)- QNetworkAccessManager
- 1 简介
- 2 公有类型
- 3 函数
- 3.1 addStrictTransportSecurityHosts
- 3.2 autoDeleteReplies
- 3.3 cache
- 3.4 clearAccessCache
- 3.5 clearConnectionCache
- 3.6 connectToHost
- 3.7 connectToHostEncrypted
- 3.8 cookieJar
- 3.9 deleteResource
- 3.10 enableStrictTransportSecurityStore
- 3.11 get
- 3.12 head
- 3.13 isStrictTransportSecurityEnabled
- 3.14 isStrictTransportSecurityStoreEnabled
- 3.15 post
- 3.16 proxy
- 3.17 proxyFactory
- 3.18 put
- 3.19 redirectPolicy
- 3.20 sendCustomReques
- 3.21 setAutoDeleteReplies
- 3.22 setCache
- 4 Signals
- 5 Protected Functions
- 6 Protected Slots
1 简介
QNetworkAccessManager是Qt网络模块中的一个类,它用于管理网络请求和响应。它可以发送HTTP请求,处理HTTP响应,支持文件上传和下载,以及支持多种网络协议。
QNetworkAccessManager使用异步方式发送请求和处理响应,这意味着它可以在不阻塞应用程序UI线程的情况下进行网络通信。当一个请求被发送时,QNetworkAccessManager将立即返回一个QNetworkReply对象,该对象可以用于监视请求的进度,访问响应数据以及处理响应错误。
QNetworkAccessManager可以使用各种不同的请求类型,包括GET、POST、PUT、DELETE等。它还支持设置请求头、查询参数、表单数据等,以及可以设置代理服务器。
使用QNetworkAccessManager发送HTTP请求的基本流程如下:
- 创建QNetworkAccessManager对象
- 创建QNetworkRequest对象,设置请求URL和请求头
- 使用QNetworkAccessManager的get()、post()、put()等函数发送请求
- 处理QNetworkReply对象以获取响应数据
QNetworkAccessManager可以方便地集成到Qt应用程序中,使应用程序可以与远程服务器进行通信。
2 公有类型
3 函数
3.1 addStrictTransportSecurityHosts
void addStrictTransportSecurityHosts(const QVector<QHstsPolicy> &knownHosts)
addStrictTransportSecurityHosts是QNetworkConfigurationManager类中的一个函数,用于向已知主机列表中添加HSTS(HTTP Strict Transport Security)策略。
HSTS是一种Web安全策略,通过HTTP响应头告知浏览器只能使用HTTPS连接来访问该网站,从而提高安全性。在服务器发送HSTS响应头后,浏览器将在一段时间内(通常是几个月)内记住该主机的HSTS策略,并自动将所有未来的HTTP请求重定向到HTTPS。当然,这仅适用于已经使用过HTTPS的站点。
在Qt中,可以使用QHstsPolicy类来表示一个主机的HSTS策略,其构造函数接受一个主机名和一个时间戳参数。可以通过调用addStrictTransportSecurityHosts函数向QNetworkConfigurationManager添加一个或多个已知的主机的HSTS策略,从而增强应用程序的网络安全性。
函数参数knownHosts是一个QVector类型的向量,包含要添加的主机列表。
3.2 autoDeleteReplies
bool QNetworkAccessManager::autoDeleteReplies() const
QNetworkAccessManager::autoDeleteReplies()是一个函数,用于返回当前QNetworkAccessManager是否配置为自动删除QNetworkReply对象。如果设置为自动删除,QNetworkAccessManager将在QNetworkReply对象完成后自动删除该对象,否则QNetworkReply对象需要手动删除。
该函数在Qt 5.14版本中引入。
默认情况下,QNetworkAccessManager的自动删除QNetworkReply的功能是启用的,这意味着当QNetworkReply对象完成后,QNetworkAccessManager将自动删除该对象。如果你想手动管理QNetworkReply对象的生命周期,可以通过调用QNetworkAccessManager的setAutoDeleteReplies(false)来禁用自动删除功能,然后手动删除QNetworkReply对象
3.3 cache
QAbstractNetworkCache *QNetworkAccessManager::cache() const
QNetworkAccessManager::cache()是一个函数,用于获取QNetworkAccessManager使用的网络数据缓存。返回的是一个指向QAbstractNetworkCache对象的指针。
QNetworkAccessManager可以使用缓存来存储从网络获取的数据,从而避免重复下载数据。如果应用程序需要在多个网络请求之间共享数据,可以使用缓存。默认情况下,QNetworkAccessManager使用QNetworkDiskCache类来管理网络数据缓存,该类将缓存数据保存在磁盘上。可以使用setCache()函数来设置其他类型的缓存,例如QNetworkMemoryCache,该类将缓存数据保存在内存中。
void QNetworkAccessManager::setCache(QAbstractNetworkCache *cache)
QNetworkAccessManager::setCache()是一个函数,用于设置QNetworkAccessManager使用的网络数据缓存。可以通过传递指向QAbstractNetworkCache对象的指针来设置缓存。QNetworkAccessManager将在处理所有网络请求时使用指定的缓存。需要注意的是,QNetworkAccessManager将拥有缓存对象的所有权,并负责在合适的时间删除缓存对象。
默认情况下,QNetworkAccessManager没有设置网络数据缓存。可以使用setCache()函数来设置其他类型的缓存,例如QNetworkMemoryCache或QNetworkDiskCache。设置网络数据缓存可以提高应用程序的性能,因为这样可以避免重复下载数据
3.4 clearAccessCache
void QNetworkAccessManager::clearAccessCache()
QNetworkAccessManager::clearAccessCache()是一个函数,用于刷新QNetworkAccessManager内部的身份验证数据和网络连接缓存。该函数通常用于自动化测试等情况下,需要清空缓存来进行多个独立测试的场合。
QNetworkAccessManager维护一个内部缓存,用于存储身份验证信息和网络连接信息,以便在未来的请求中重用这些信息。在某些情况下,可能需要清空这些缓存,例如在进行多个独立测试时,以确保每个测试的环境都是独立的。
以下是一个示例代码,展示了如何使用QNetworkAccessManager::clearAccessCache()函数清空访问缓存:
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 向manager发送请求,填充缓存
// 执行测试
// ...
// 清空缓存
manager->clearAccessCache();
// 执行下一个测试
// ...
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象,并发送一些请求,以填充内部缓存。然后,执行一些测试代码,之后调用clearAccessCache()函数清空访问缓存,以确保下一个测试环境是独立的。需要注意的是,clearAccessCache()函数只清空身份验证数据和网络连接信息的缓存,而不会清空其他缓存,例如DNS缓存或网络数据缓存。如果需要清空其他缓存,请使用相关的函数,例如QNetworkDiskCache::clear()函数。
3.5 clearConnectionCache
void QNetworkAccessManager::clearConnectionCache()
QNetworkAccessManager::clearConnectionCache()是一个函数,用于刷新QNetworkAccessManager内部的网络连接缓存。与clearAccessCache()不同的是,该函数保留身份验证数据。
该函数在Qt 5.9版本中引入。
QNetworkAccessManager维护一个内部缓存,用于存储网络连接信息,以便在未来的请求中重用这些信息。在某些情况下,可能需要清空这些缓存,例如在进行多个独立测试时,以确保每个测试的环境都是独立的。与clearAccessCache()不同,clearConnectionCache()只清空网络连接缓存,而保留身份验证数据。
3.6 connectToHost
void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port = 80)
QNetworkAccessManager::connectToHost()是一个函数,用于在发起HTTP请求之前,建立到指定主机的TCP连接。该函数可以降低网络延迟,提高HTTP请求的响应速度。
该函数在Qt 5.2版本中引入。
QNetworkAccessManager默认是在HTTP请求时,自动建立到目标主机的TCP连接。这意味着当你发起HTTP请求时,QNetworkAccessManager会自动完成TCP握手,建立TCP连接,并在该连接上发送HTTP请求。使用connectToHost()函数可以在发起HTTP请求之前,手动建立到主机的TCP连接,从而降低网络延迟。
需要注意的是,connectToHost()函数没有错误报告的可能性,因此,建议使用QNetworkAccessManager默认的自动连接功能,除非你有充分的理由需要手动建立TCP连接。
以下是一个示例代码,展示了如何使用QNetworkAccessManager::connectToHost()函数手动建立到主机的TCP连接:
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 建立到主机的TCP连接
manager->connectToHost("www.example.com", 80);
// 发起HTTP请求
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl("http://www.example.com")));
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 处理响应数据
QByteArray data = reply->readAll();
qDebug() << "Received data:" << data;
});
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象,然后使用connectToHost()函数手动建立到主机的TCP连接。接着发送一个GET请求,获取QNetworkReply对象,并处理响应数据。需要注意的是,由于connectToHost()函数没有错误报告的可能性,因此必须在发起HTTP请求之前,确保TCP连接已经成功建立。如果TCP连接未能成功建立,则可能导致HTTP请求失败或超时。
3.7 connectToHostEncrypted
void connectToHostEncrypted(const QString &hostName, quint16 port = 443, const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration())
void connectToHostEncrypted(const QString &hostName, quint16 port, const QSslConfiguration &sslConfiguration, const QString &peerName)
QNetworkAccessManager::connectToHostEncrypted()是一个函数,用于在发起HTTPS请求之前,建立到指定主机的安全TCP连接。该函数可以手动建立到主机的安全TCP连接,从而提高HTTPS请求的响应速度。
该函数可以有两个版本,其中一个版本需要提供peerName参数,用于验证服务器的证书。
这两个函数在Qt 4.6版本中引入。
QNetworkAccessManager默认情况下是在HTTPS请求时,自动建立到目标主机的安全TCP连接。这意味着当你发起HTTPS请求时,QNetworkAccessManager会自动完成SSL握手,建立安全TCP连接,并在该连接上发送HTTPS请求。使用connectToHostEncrypted()函数可以在发起HTTPS请求之前,手动建立到主机的安全TCP连接,从而提高HTTPS请求的响应速度。
以下是一个示例代码,展示了如何使用QNetworkAccessManager::connectToHostEncrypted()函数手动建立到主机的安全TCP连接:
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 建立到主机的安全TCP连接
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
sslConfig.setProtocol(QSsl::TlsV1_2);
manager->connectToHostEncrypted("www.example.com", 443, sslConfig);
// 发起HTTPS请求
QNetworkRequest request(QUrl("https://www.example.com"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QNetworkReply *reply = manager->post(request, QByteArray("hello"));
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 处理响应数据
QByteArray data = reply->readAll();
qDebug() << "Received data:" << data;
});
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象,然后使用connectToHostEncrypted()函数手动建立到主机的安全TCP连接。接着发送一个POST请求,获取QNetworkReply对象,并处理响应数据。需要注意的是,由于connectToHostEncrypted()函数需要手动建立安全TCP连接,因此必须在发起HTTPS请求之前,确保安全TCP连接已经成功建立。如果安全TCP连接未能成功建立,则可能导致HTTPS请求失败或超时。另外,如果使用需要peerName参数的函数,需要提供正确的服务器证书名称进行验证,否则将无法建立安全连接。
3.8 cookieJar
QNetworkCookieJar * cookieJar() const
QNetworkAccessManager::cookieJar()是一个函数,用于返回QNetworkAccessManager正在使用的cookie jar对象。Cookie jar用于存储和管理QNetworkAccessManager处理的所有HTTP cookies。
HTTP cookie是服务器在客户端存储的一小段文本信息,用于跟踪用户会话和识别用户。QNetworkAccessManager默认会自动管理HTTP cookie,包括从服务器接收cookie和在后续请求中发送cookie。可以通过设置QNetworkAccessManager的cookie jar对象来管理HTTP cookie,以便在多个请求之间共享cookie信息。
void QNetworkAccessManager::setCookieJar(QNetworkCookieJar *cookieJar)
QNetworkAccessManager::setCookieJar()是一个函数,用于设置QNetworkAccessManager正在使用的cookie jar对象。Cookie jar用于存储和管理QNetworkAccessManager处理的所有HTTP cookies。
HTTP cookie是服务器在客户端存储的一小段文本信息,用于跟踪用户会话和识别用户。QNetworkAccessManager默认会自动管理HTTP cookie,包括从服务器接收cookie和在后续请求中发送cookie。可以通过设置QNetworkAccessManager的cookie jar对象来管理HTTP cookie,以便在多个请求之间共享cookie信息。
以下是一个示例代码,展示了如何使用QNetworkAccessManager::setCookieJar()函数设置cookie jar对象:
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 设置cookie jar
QNetworkCookieJar *cookieJar = new MyCookieJar();
manager->setCookieJar(cookieJar);
// 发起HTTP请求
QNetworkRequest request(QUrl("http://www.example.com"));
QNetworkReply *reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 处理响应数据
QByteArray data = reply->readAll();
qDebug() << "Received data:" << data;
});
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象,然后使用setCookieJar()函数设置cookie jar对象为一个自定义的MyCookieJar对象。接着,我们发送一个GET请求,获取QNetworkReply对象,并处理响应数据。需要注意的是,在实际使用中,如果需要对cookie进行更复杂的管理,可以实现自己的QNetworkCookieJar子类,并重写QNetworkCookieJar::cookiesForUrl()和QNetworkCookieJar::setCookiesFromUrl()函数,以便实现自己的安全策略。
3.9 deleteResource
QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request)
QNetworkAccessManager::deleteResource()是一个函数,用于发送一个HTTP DELETE请求,删除由request标识的URL对应的资源。该函数只能用于HTTP协议。
HTTP DELETE请求用于请求服务器删除指定URL对应的资源。使用QNetworkAccessManager的deleteResource()函数可以方便地向服务器发送DELETE请求。
3.10 enableStrictTransportSecurityStore
void QNetworkAccessManager::enableStrictTransportSecurityStore(bool enabled, const QString &storeDir = QString())
QNetworkAccessManager::enableStrictTransportSecurityStore()是一个函数,用于启用或禁用内部的HSTS缓存,并将HSTS策略写入持久化存储。如果启用了持久化存储,storeDir参数指定了持久化存储的路径。如果storeDir参数为空字符串,则存储路径默认为QStandardPaths::CacheLocation,即缓存目录。如果没有可写的缓存目录,并且storeDir为空字符串,则存储路径将在程序的工作目录中。
需要注意的是,如果启用持久化存储,QNetworkAccessManager会将HSTS策略写入磁盘,并从磁盘读取缓存中的策略。在启用持久化存储之前,如果缓存中已经包含了一些HSTS策略,则这些策略将会被保留在缓存中,并且缓存中的策略会覆盖磁盘中的策略。因此,在启用持久化存储之前,应该清空缓存。另外,如果缓存和持久化存储中都包含了相同的主机名和HSTS策略,缓存中的策略将被认为是最新的,并覆盖持久化存储中的策略。
3.11 get
QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
QNetworkAccessManager::get()是一个函数,用于发送一个HTTP GET请求,并返回一个新的QNetworkReply对象,用于读取响应数据。在获取到新数据时,QNetworkReply对象会发出readyRead()信号。
HTTP GET请求用于请求服务器获取指定URL对应的资源。使用QNetworkAccessManager的get()函数可以方便地向服务器发送GET请求,并读取响应数据。
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 发送GET请求
QUrl url("http://www.example.com");
QNetworkRequest request(url);
QNetworkReply *reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 处理响应数据
QByteArray data = reply->readAll();
qDebug() << "Received data:" << data;
});
delete manager;
3.12 head
QNetworkReply *QNetworkAccessManager::head(const QNetworkRequest &request)
QNetworkAccessManager::head()是一个函数,用于发送一个HTTP HEAD请求,获取与请求相关的网络头,并返回一个新的QNetworkReply对象,用于包含这些头。
HTTP HEAD请求类似于HTTP GET请求,但是只返回与请求相关的HTTP头信息,而不返回实际的资源内容。通常,HTTP HEAD请求用于获取资源的元数据或检查资源是否存在,而不需要实际下载资源内容。
QNetworkAccessManager *manager = new QNetworkAccessManager();
// 发送HEAD请求
QUrl url("http://www.example.com");
QNetworkRequest request(url);
QNetworkReply *reply = manager->head(request);
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 处理响应头数据
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant contentLength = reply->header(QNetworkRequest::ContentLengthHeader);
qDebug() << "Status code:" << statusCode.toInt();
qDebug() << "Content length:" << contentLength.toInt();
});
delete manager;
3.13 isStrictTransportSecurityEnabled
bool QNetworkAccessManager::isStrictTransportSecurityEnabled() const
QNetworkAccessManager::isStrictTransportSecurityEnabled()是一个函数,用于判断HTTP Strict Transport Security (HSTS)是否已启用。如果已启用,返回true;否则返回false。默认情况下,HSTS是禁用的。
HTTP Strict Transport Security (HSTS)是一种安全机制,用于保护Web应用程序免受SSL剥离攻击和会话劫持攻击。当客户端和服务器首次建立HTTPS连接时,服务器可以向客户端发送HSTS响应头,要求客户端在接下来的一段时间内(例如6个月)始终使用HTTPS访问该站点。在HSTS生命周期内,如果客户端尝试使用HTTP连接到该站点,浏览器会自动将请求重定向到HTTPS。
3.14 isStrictTransportSecurityStoreEnabled
bool QNetworkAccessManager::isStrictTransportSecurityStoreEnabled() const
QNetworkAccessManager::isStrictTransportSecurityStoreEnabled()是一个函数,用于判断HTTP Strict Transport Security (HSTS)缓存是否已启用持久化存储。如果已启用,返回true;否则返回false。
3.15 post
QNetworkReply * post(const QNetworkRequest &request, QIODevice *data)
QNetworkReply * post(const QNetworkRequest &request, const QByteArray &data)
QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
第一种重载形式中,data参数是一个QIODevice对象,可以用于发送二进制数据、文件数据等。下面是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/upload"));
QFile *file = new QFile("test.txt");
file->open(QIODevice::ReadOnly);
QNetworkReply *reply = manager->post(request, file);
file->setParent(reply); // 所有者设为reply,以便reply析构时能够关闭文件
// 处理reply的数据读取等操作
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,然后创建一个QFile对象,并用open()函数打开文件。最后,我们使用QNetworkAccessManager的post()函数发送文件内容,并将文件对象设置为QNetworkReply对象的子对象。在reply被析构时,文件对象也会被自动关闭。
第二种重载形式中,data参数是一个QByteArray对象,可以用于发送纯文本数据、JSON数据等。下面是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/api"));
QByteArray postData;
postData.append("username=johndoe&password=secret");
QNetworkReply *reply = manager->post(request, postData);
// 处理reply的数据读取等操作
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,然后创建一个QByteArray对象,并将POST数据写入该对象。最后,我们使用QNetworkAccessManager的post()函数发送POST请求,并处理reply对象的数据读取等操作。
第三种重载形式中,multiPart参数是一个QHttpMultiPart对象,可以用于发送文件、表单数据等。QHttpMultiPart是一个较为复杂的对象,可以包含多个QHttpPart对象。以下是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/upload"));
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"username\""));
textPart.setBody("johndoe");
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"test.jpg\""));
QFile *file = new QFile("test.jpg");
file->open(QIODevice::ReadOnly);
filePart.setBodyDevice(file);
file->setParent(multiPart); // 所有者设为multiPart,以便multiPart析构时能够关闭文件
multiPart->append(textPart);
multiPart->append(filePart);
QNetworkReply *reply = manager->post(request, multiPart);
multiPart->setParent(reply); // 所有者设为reply,以便reply析构时能够删除multiPart
// 处理reply的数据读取等操作
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,然后创建一个QHttpMultiPart对象,并创建两个QHttpPart对象用于发送纯文本数据和文件数据。最后,我们使用QNetworkAccessManager的post()函数发送POST请求,并将QHttpMultiPart对象设置为QNetworkReply对象的子对象。在reply被析构时,QHttpMultiPart对象也会被自动删除。
3.16 proxy
QNetworkProxy proxy() const
该函数返回QNetworkAccessManager对象的代理服务器配置。如果QNetworkAccessManager对象没有设置代理服务器,则返回一个空的QNetworkProxy对象。
3.17 proxyFactory
QNetworkProxyFactory * proxyFactory() const
该函数返回QNetworkAccessManager对象的代理工厂。代理工厂用于创建QNetworkProxy对象,以便QNetworkAccessManager对象可以使用代理服务器转发网络请求。如果QNetworkAccessManager对象没有设置代理工厂,则返回一个空的QNetworkProxyFactory对象。
3.18 put
QNetworkReply * put(const QNetworkRequest &request, QIODevice *data)
QNetworkReply * put(const QNetworkRequest &request, const QByteArray &data)
QNetworkReply * put(const QNetworkRequest &request, QHttpMultiPart *multiPart)
第一种重载形式中,data参数是一个QIODevice对象,可以用于发送二进制数据、文件数据等。下面是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/upload"));
QFile *file = new QFile("test.txt");
file->open(QIODevice::ReadOnly);
QNetworkReply *reply = manager->put(request, file);
file->setParent(reply); // 所有者设为reply,以便reply析构时能够关闭文件
// 处理reply的数据读取等操作
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,然后创建一个QFile对象,并用open()函数打开文件。最后,我们使用QNetworkAccessManager的put()函数发送文件内容,并将文件对象设置为QNetworkReply对象的子对象。在reply被析构时,文件对象也会被自动关闭。
第二种重载形式中,data参数是一个QByteArray对象,可以用于发送纯文本数据、JSON数据等。下面是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/api"));
QByteArray putData;
putData.append("username=johndoe&password=secret");
QNetworkReply *reply = manager->put(request, putData);
// 处理reply的数据读取等操作
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,然后创建一个QByteArray对象,并将PUT数据写入该对象。最后,我们使用QNetworkAccessManager的put()函数发送PUT请求,并处理reply对象的数据读取等操作。
第三种重载形式中,multiPart参数是一个QHttpMultiPart对象,可以用于发送文件、表单数据等。QHttpMultiPart是一个较为复杂的对象,可以包含多个QHttpPart对象。以下是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/upload"));
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"username\""));
textPart.setBody("johndoe");
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"test.jpg\""));
QFile *file = new QFile("test.jpg");
file->open(QIODevice::ReadOnly);
filePart.setBodyDevice(file);
file->setParent(multiPart); // 所有者设为multiPart,以便multiPart析构时能够关闭文件
multiPart->append(textPart);
multiPart->append(filePart);
QNetworkReply *reply = manager->put(request, multiPart);
multiPart->setParent(reply); // 所有者设为reply,以便reply析构时能够删除multiPart
// 处理reply的数据读取等操作
delete manager;
3.19 redirectPolicy
QNetworkRequest::RedirectPolicy redirectPolicy() const
QNetworkRequest类中的redirectPolicy()函数可以用于获取网络请求的重定向策略。重定向是指当网络请求的URL发生变化时,服务器会向客户端返回一个重定向响应,以便客户端跳转到新的URL上。重定向策略决定了网络请求在遇到重定向响应时的行为。
该函数返回QNetworkRequest对象的重定向策略,它是一个QNetworkRequest::RedirectPolicy类型的枚举值。以下是QNetworkRequest::RedirectPolicy类型的枚举值:
- QNetworkRequest::ManualRedirectPolicy:表示网络请求遇到重定向响应时,不会自动跳转到新的URL上,而是会发出finished()信号,由程序员决定是否进行跳转。
- QNetworkRequest::AutoRedirectPolicy:表示网络请求遇到重定向响应时,会自动跳转到新的URL上。
- QNetworkRequest::NoLessSafeRedirectPolicy:表示网络请求遇到重定向响应时,只会跳转到比原URL更安全的URL上。
- QNetworkRequest::SameOriginRedirectPolicy:表示网络请求遇到重定向响应时,只会跳转到与原URL属于同一个域名的URL上。
以下是一个示例代码:
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://www.example.com/old_url"));
// 设置重定向策略为ManualRedirectPolicy
request.setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
QNetworkReply *reply = manager->get(request);
connect(reply, &QNetworkReply::finished, [=]() {
if (reply->error() == QNetworkReply::NoError) {
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
qDebug() << "The request was redirected to" << redirectUrl;
// 手动跳转到新的URL上
request.setUrl(redirectUrl);
reply = manager->get(request);
} else {
qDebug() << "Failed to perform the request:" << reply->errorString();
}
reply->deleteLater();
});
delete manager;
在这个示例中,我们首先创建一个QNetworkAccessManager对象和一个QNetworkRequest对象,并将重定向策略设置为ManualRedirectPolicy。接着,我们使用QNetworkAccessManager的get()函数发送网络请求,当请求完成时,会发出finished()信号。在信号槽函数中,我们判断请求是否成功,如果成功,则获取重定向URL,并使用QNetworkAccessManager的get()函数手动跳转到新的URL上。如果请求失败,则输出错误信息。
注意:在上述示例中,我们手动跳转到新的URL上,这可能会导致一些安全问题,因此在实际开发中应该谨慎使用ManualRedirectPolicy策略。一般情况下,我们建议使用AutoRedirectPolicy策略。
3.20 sendCustomReques
QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr)
QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data)
QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart)
QNetworkAccessManager类中的sendCustomRequest()函数可以用于发送自定义的网络请求,这些网络请求可以使用任意的HTTP方法(如GET、POST、PUT等)。这些自定义的请求不同于QNetworkAccessManager中提供的get()、post()、put()等函数,因为它们使用了自定义的HTTP方法,因此我们需要手动设置请求头。
3.21 setAutoDeleteReplies
void setAutoDeleteReplies(bool shouldAutoDelete)
3.22 setCache
void setCache(QAbstractNetworkCache *cache)
void setCookieJar(QNetworkCookieJar *cookieJar)
void setProxy(const QNetworkProxy &proxy)
void setProxyFactory(QNetworkProxyFactory *factory)
void setRedirectPolicy(QNetworkRequest::RedirectPolicy policy)
void setStrictTransportSecurityEnabled(bool enabled)
void setTransferTimeout(int timeout = QNetworkRequest::DefaultTransferTimeoutConstant)
QVector<QHstsPolicy> strictTransportSecurityHosts() const
QStringList supportedSchemes() const
int transferTimeout() const
4 Signals
void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
void encrypted(QNetworkReply *reply)
void finished(QNetworkReply *reply)
void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
5 Protected Functions
virtual QNetworkReply * createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &originalReq, QIODevice *outgoingData = nullptr)
6 Protected Slots
QStringList supportedSchemesImplementation() const