QNetworkRequest
QNetworkRequest 是网络访问功能的一部分,它构造一个请求,它可以是以下之一:
GET: get(…)
POST: post(…)
PUT: put(…)
DELETE: deleteResource(…)
HEAD: head(…)
标头可以使用 setHeader 设置为已知标头,并且可以是以下之一:
ContentDispositionHeader 内容处置头
ContentTypeHeader 内容类型标题
ContentLengthHeader 内容长度标题
LocationHeader 位置标题
LastModifiedHeader 最后修改头
CookieHeader Cookie头
SetCookieHeader 设置CookieHeader
UserAgentHeader 用户代理头
ServerHeader 服务器头
setRawHeader 设置原始或自定义标头
setAttribute 来设置HTTP 属性帮助控制请求缓存、重定向和 cookie
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QNetworkReply>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
void doRequest();
void replyFinished(QNetworkReply *reply);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QJsonDocument>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
doRequest();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::doRequest()
{
//QNetworkRequest 是需要用来从网络请求操作的东西,比如 get 和 put
//QNetworkRequest 也可以将 QUrl 作为其参数
//QNetworkRequest 不是基于 QObject,因此它没有父级,也没有任何自己的信号。 所有通信都是通过 QNetworkAccessManager 完成的
QNetworkRequest request;
request.setUrl(QUrl("http://www.example.com"));
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//您要连接的一个信号是finished
//假设我有一些表单数据需要传输; 我需要使用 setHeader 添加一个标准标题。 我还可以添加以下自定义标头,我称之为 X-UUID:
//request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
//request.setRawHeader(QByteArray("X-UUID"), QUuid::createUuid().toByteArray());
connect(manager, &QNetworkAccessManager::finished,this, &MainWindow::replyFinished);
manager->get(request);
}
void MainWindow::replyFinished(QNetworkReply *reply)
{
//获取数据回调函数
if (reply->error())
ui->textEdit->insertPlainText( reply->errorString());
else {
QList<QByteArray> headerList = reply->rawHeaderList();
ui->textEdit->insertPlainText(headerList.join("\n") +"\n");
QByteArray responsData = reply->readAll();
ui->textEdit->insertHtml(responsData);
}
}
// if (reply->rawHeader(head).contains("json")) {
// QJsonDocument json = QJsonDocument::fromJson(response_data);
// qWarning(json);
// }
QNetworkAccessManager
引入管理器——QNetworkAccessManager (QNAM)。 它用于通过网络发送和接收异步请求。 通常,一个应用程序中有一个 QNAM 实例,如下所示:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
最简单的是,您可以使用 get、put、post、deleteResource 或 head 函数发出 QNAM 请求。
QNAM 使用信号来传输数据和请求信息,而finished() 信号用于在请求完成时发出信号。
connect(manager, &QNetworkAccessManager::finished, this, &MainWindow::replyFinished);
这将使用 QNetworkReply 参数中的数据和标头调用您的 replyFinished 槽,如下所示:
void MainWindow::replyFinished(QNetworkReply *reply)
{
if (reply->error())
ui->textEdit->insertPlainText( reply->errorString());
else {
QList<QByteArray> headerList = reply->rawHeaderList();
ui->textEdit->insertPlainText(headerList.join("\n") +"\n");
QByteArray responsData = reply->readAll();
ui->textEdit->insertHtml(responsData);
}
}
然后,在 QNetworkAccessManager 上调用 get 方法,如下所示:
manager->get(request);
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QDir>
#include <QFileDialog>
#include <QFile>
#include <QUrlQuery>
#include <QHttpPart>
#include <QHttpMultiPart>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
on_lineEdit_returnPressed();
// send file
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request;
request.setUrl(QUrl(serverUrl));
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::AnyFile);
QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath());
if (!filename.isEmpty()) {
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray fileBytes = file.readAll();
manager->put(request, fileBytes);
}
}
}
void MainWindow::on_pushButton_2_clicked()
{
on_lineEdit_returnPressed();
// send form
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request;
QUrl url(serverUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QUrlQuery formData;
formData.addQueryItem("login", "me");
formData.addQueryItem("password", "123");
formData.addQueryItem("submit", "Send");
url.setQuery(formData);
request.setUrl(url);
manager->get(request);
}
void MainWindow::on_lineEdit_returnPressed()
{
// url changed
serverUrl = ui->lineEdit->text();
}
void MainWindow::on_pushButton_3_clicked()
{
// post
on_lineEdit_returnPressed();
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request;
QUrl url(serverUrl);
QByteArray postData;
postData.append("?login=me&password=123&submit=Send+data");
manager->post(request, postData);
}
void MainWindow::on_pushButton_4_clicked()
{
// multipart
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request;
QUrl url(serverUrl);
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::AnyFile);
QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath());
if (filename.isEmpty())
return;
QFile *file = new QFile(filename);
if (file->open(QIODevice::ReadOnly)) {
QByteArray fileBytes = file->readAll();
QHttpMultiPart *multiPart =
new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"filename\""));
textPart.setBody(filename.toLocal8Bit());
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"file\""));
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/zip"));
filePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(textPart);
multiPart->append(filePart);
manager->put(request, multiPart);
}
}
创建文件上传的方法也同样简单。 当然你的web服务器需要支持put方法,如下:
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::AnyFile);
QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath());
if (!filename.isEmpty()) {
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray fileBytes = file.readAll();
manager->put(request, fileBytes);
}
}
如果需要在URL中发送一些查询参数,可以使用QUrlQuery构造表单查询数据,然后发送请求如下:
QNetworkRequest request;
QUrl url("http://www.example.com");
QUrlQuery formData;
formData.addQueryItem("login", "me");
formData.addQueryItem("password", "123");
formData.addQueryItem("submit", "Send");
url.setQuery(formData);
request.setUrl(url);
manager->get(request);
表单数据可以通过 post 函数作为 QByteArray 上传,如下所示:
QByteArray postData;
postData.append("?login=me&password=123&submit=Send");
manager->post(request, postData);
要发送多部分表单数据,例如表单数据和图像,您可以使用 QHttpMultiPart 如下:
QFile *file = new QFile(filename);
if (file->open(QIODevice::ReadOnly)) {
QByteArray fileBytes = file->readAll();
QHttpMultiPart *multiPart =
new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"filename\""));
textPart.setBody(filename.toLocal8Bit());
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\""));
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/zip"));
filePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(textPart);
multiPart->append(filePart);
manager->put(request, multiPart);
}