This commit is contained in:
朱子楚\zhuzi 2023-07-23 20:44:43 +08:00
parent 4d78262277
commit f141af154a
3 changed files with 176 additions and 102 deletions

View File

@ -26,6 +26,7 @@ FluScrollablePage{
} }
onError: onError:
(status,errorString)=>{ (status,errorString)=>{
console.debug(status+"->"+errorString)
showError(errorString) showError(errorString)
} }
onSuccess: onSuccess:
@ -59,6 +60,7 @@ FluScrollablePage{
FluHttp{ FluHttp{
id:http_download id:http_download
url:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" url:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
// url:"https://www.w3school.com.cn/example/html5/mov_bbb.mp4"
onStart: { onStart: {
btn_download.disabled = true btn_download.disabled = true
} }
@ -94,7 +96,8 @@ FluScrollablePage{
FluButton{ FluButton{
text:"Get请求" text:"Get请求"
onClicked: { onClicked: {
http_get.get({q:"FluentUI"}) http_download.cancel()
// http_get.get({q:"FluentUI"})
} }
} }
FluButton{ FluButton{

View File

@ -9,9 +9,6 @@ using namespace AeaQt;
FluHttp::FluHttp(QObject *parent) FluHttp::FluHttp(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
enabledBreakpointDownload(false);
timeout(15);
retry(3);
} }
@ -20,140 +17,193 @@ FluHttp::~FluHttp(){
} }
void FluHttp::cancel(){ void FluHttp::cancel(){
foreach (auto item, cache) { foreach (QPointer<QNetworkReply> item, _cache) {
if(item){ if(item){
qDebug()<<item;
item->abort(); item->abort();
} }
} }
} }
void FluHttp::handleReply(QNetworkReply* reply){ void FluHttp::handleReply(QNetworkReply* reply){
cache.append(reply); _cache.append(reply);
} }
void FluHttp::postString(QString params,QVariantMap headers){ void FluHttp::postString(QString params,QVariantMap headers){
QVariantMap request = invokeIntercept(params,headers,"postString").toMap(); QVariantMap data = invokeIntercept(params,headers,"postString").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
HttpClient client; QNetworkAccessManager manager;
client.initReplyCompleted = [=](QNetworkReply* reply){ handleReply(reply); }; QUrl url(_url);
client.post(_url) QNetworkRequest request(url);
.retry(retry()) addHeaders(&request,data["headers"].toMap());
.timeout(timeout()) QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
.bodyWithRaw(request[params].toString().toUtf8()) QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary());
.headers(request["headers"].toMap()) request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
.onSuccess([=](QString result) { for (const auto& each : data["params"].toMap().toStdMap())
Q_EMIT success(result); {
}) const QString& key = each.first;
.onFailed([=](QNetworkReply* reply) { const QString& value = each.second.toString();
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
}) QHttpPart part;
.block() part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
.exec(); part.setBody(value.toUtf8());
multiPart->append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,multiPart);
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (reply->error() == QNetworkReply::NoError) {
Q_EMIT success(QString::fromUtf8(reply->readAll()));
}else{
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
}
reply->deleteLater();
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
void FluHttp::post(QVariantMap params,QVariantMap headers){ void FluHttp::post(QVariantMap params,QVariantMap headers){
QVariantMap request = invokeIntercept(params,headers,"post").toMap(); QVariantMap data = invokeIntercept(params,headers,"post").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
HttpClient client; QNetworkAccessManager manager;
client.initReplyCompleted = [=](QNetworkReply* reply){ handleReply(reply); }; QUrl url(_url);
client.post(_url) QNetworkRequest request(url);
.retry(retry()) addHeaders(&request,data["headers"].toMap());
.timeout(timeout()) QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
.headers(headers) QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary());
.bodyWithFormData(request["params"].toMap()) request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
.headers(request["headers"].toMap()) for (const auto& each : data["params"].toMap().toStdMap())
.onSuccess([=](QString result) { {
Q_EMIT success(result); const QString& key = each.first;
}) const QString& value = each.second.toString();
.onFailed([=](QNetworkReply* reply) { QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); QHttpPart part;
}) part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
.block() part.setBody(value.toUtf8());
.exec(); multiPart->append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,multiPart);
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (reply->error() == QNetworkReply::NoError) {
Q_EMIT success(QString::fromUtf8(reply->readAll()));
}else{
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
}
reply->deleteLater();
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
void FluHttp::postJson(QVariantMap params,QVariantMap headers){ void FluHttp::postJson(QVariantMap params,QVariantMap headers){
QVariantMap request = invokeIntercept(params,headers,"postJson").toMap(); QVariantMap data = invokeIntercept(params,headers,"postJson").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
HttpClient client; QNetworkAccessManager manager;
client.initReplyCompleted = [=](QNetworkReply* reply){ handleReply(reply); }; QUrl url(_url);
client.post(_url) QNetworkRequest request(url);
.retry(retry()) addHeaders(&request,data["headers"].toMap());
.timeout(timeout()) QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
.headers(headers) QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary());
.bodyWithRaw(QJsonDocument::fromVariant(request["params"]).toJson()) request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
.headers(request["headers"].toMap()) for (const auto& each : data["params"].toMap().toStdMap())
.onSuccess([=](QString result) { {
Q_EMIT success(result); const QString& key = each.first;
}) const QString& value = each.second.toString();
.onFailed([=](QNetworkReply* reply) { QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); QHttpPart part;
}) part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
.block() part.setBody(value.toUtf8());
.exec(); multiPart->append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,multiPart);
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (reply->error() == QNetworkReply::NoError) {
Q_EMIT success(QString::fromUtf8(reply->readAll()));
}else{
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
}
reply->deleteLater();
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
void FluHttp::get(QVariantMap params,QVariantMap headers){ void FluHttp::get(QVariantMap params,QVariantMap headers){
QVariantMap request = invokeIntercept(params,headers,"get").toMap(); QVariantMap data = invokeIntercept(params,headers,"get").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
HttpClient client; QNetworkAccessManager manager;
client.initReplyCompleted = [=](QNetworkReply* reply){ handleReply(reply); }; QUrl url(_url);
client.get(_url) addQueryParam(&url,data["params"].toMap());
.retry(retry()) QNetworkRequest request(url);
.timeout(timeout()) addHeaders(&request,data["headers"].toMap());
.queryParams(request["params"].toMap()) QEventLoop loop;
.headers(request["headers"].toMap()) QNetworkReply* reply = manager.get(request);
.onSuccess([=](QString result) { connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
Q_EMIT success(result); loop.exec();
}) if (reply->error() == QNetworkReply::NoError) {
.onFailed([=](QNetworkReply* reply) { Q_EMIT success(QString::fromUtf8(reply->readAll()));
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); }else{
}) Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
.block() }
.exec(); reply->deleteLater();
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
void FluHttp::download(QString path,QVariantMap params,QVariantMap headers){ void FluHttp::download(QString path,QVariantMap params,QVariantMap headers){
QPointer<FluHttp> weakThis(this); QVariantMap data = invokeIntercept(params,headers,"download").toMap();
QVariantMap request = invokeIntercept(params,headers,"download").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
HttpClient client; QNetworkAccessManager manager;
client.initReplyCompleted = [=](QNetworkReply* reply){ handleReply(reply); }; QUrl url(_url);
client.get(_url) addQueryParam(&url,data["params"].toMap());
.retry(retry()) QNetworkRequest request(url);
.timeout(timeout()) addHeaders(&request,data["headers"].toMap());
.download(path) QFile *file = new QFile(path);
.enabledBreakpointDownload(_enabledBreakpointDownload) QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
.queryParams(request["params"].toMap()) if (!file->open(mode))
.headers(request["headers"].toMap()) {
.onDownloadProgress([=](qint64 recv, qint64 total) { Q_EMIT error(-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()));
if (!weakThis) { file->deleteLater();
return; file = nullptr;
} Q_EMIT finish();
Q_EMIT weakThis->downloadProgress(recv,total); return;
}) }
.onDownloadFileSuccess([=](QString result) { QEventLoop *loop = new QEventLoop();
Q_EMIT success(result); connect(&manager,&QNetworkAccessManager::finished,this,[=](QNetworkReply *reply){
}) loop->quit();
.onDownloadFileFailed([=](QString errorString) { });
Q_EMIT error(-1,errorString); QPointer<QNetworkReply> reply = manager.get(request);
}) _cache.append(reply);
.block() connect(reply,&QNetworkReply::downloadProgress,this,[=](qint64 bytesReceived, qint64 bytesTotal){
.exec(); Q_EMIT downloadProgress(bytesReceived,bytesTotal);
});
connect(reply,&QNetworkReply::readyRead,this,[=](){
file->write(reply->readAll());
});
loop->exec();
if (reply->error() == QNetworkReply::NoError) {
Q_EMIT success(path);
}else{
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
}
file->close();
loop->deleteLater();
file->deleteLater();
reply->deleteLater();
loop = nullptr;
file = nullptr;
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
@ -171,3 +221,23 @@ QVariant FluHttp::invokeIntercept(const QVariant& params,const QVariant& headers
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, requet)); QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, requet));
return target; return target;
} }
void FluHttp::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
QMapIterator<QString, QVariant> iter(params);
QUrlQuery urlQuery(*url);
while (iter.hasNext())
{
iter.next();
urlQuery.addQueryItem(iter.key(), iter.value().toString());
}
url->setQuery(urlQuery);
}
void FluHttp::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext())
{
iter.next();
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
}
}

View File

@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QFile>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include "stdafx.h" #include "stdafx.h"
@ -10,14 +11,12 @@ class FluHttp : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,url); Q_PROPERTY_AUTO(QString,url);
Q_PROPERTY_AUTO(bool,enabledBreakpointDownload)
Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(int,retry);
QML_NAMED_ELEMENT(FluHttp) QML_NAMED_ELEMENT(FluHttp)
private: private:
QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method); QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method);
void handleReply(QNetworkReply* reply); void handleReply(QNetworkReply* reply);
QList<QNetworkReply*> cache; void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
public: public:
explicit FluHttp(QObject *parent = nullptr); explicit FluHttp(QObject *parent = nullptr);
~FluHttp(); ~FluHttp();
@ -32,6 +31,8 @@ public:
Q_INVOKABLE void postString(QString params = "",QVariantMap headers = {}); Q_INVOKABLE void postString(QString params = "",QVariantMap headers = {});
Q_INVOKABLE void download(QString path,QVariantMap params = {},QVariantMap headers = {}); Q_INVOKABLE void download(QString path,QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void cancel(); Q_INVOKABLE void cancel();
private:
QList<QPointer<QNetworkReply>> _cache;
}; };
#endif // FLUHTTP_H #endif // FLUHTTP_H