由于最近做的课程作业的原因,为了减轻IM通信时对服务器造成的压力,我们决定将图片转为url后发送url。
我们选择的图床是SM.MS,它是一个免费的图床,而且经过测试上传速度还在可以忍受的范围内。
官方的API接口在 https://sm.ms/doc/v1 中,由于我们只需要上传图片所以只需要使用post然后修改post的头部,包含名为smfile的头部即可。
在实现post功能前我们踩了无数的坑,前前后后尝试了很多种方法,后期反思觉得还是由于对API理解不透彻以及对Qt的网络编程方面不熟悉,所以如果这篇文章可以帮助到你的话,我们将十分庆幸,愿你少走弯路。
采用Qt实现网络变成,首先要在pro文件中添加network
QT += core gui network
接下来就是头文件
#include <QFileDialog>
#include <QHttpMultiPart>
#include <QJsonObject>
#include <QJsonParseError>
#include <QNetworkAccessManager>
由于这只是我的一个测试程序,所以我写在了mainwindow中,你可以放在任何你需要的地方
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//网络载体
QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this);
//网络载体的响应接收信号,与响应接收槽绑定
connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(deal(QNetworkReply*)));
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
//如果上传的是jpg图片,就修改为image/jpg
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"smfile\"; filename=\"image.png\""));
//这里的smfile是参数名,不可以修改,因为SM.MS的API接口要求参数名必须为smfile
//下面这行代码的作用是打开选择窗口,选择一个图片并返回路径
QString strFilePath = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("选择上传图片"), "./", tr("Image files(*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm *.jpeg);;All files (*.*)"));
QFile *file = new QFile(strFilePath);
if(!file->open(QIODevice::ReadOnly))
qDebug()<<"=================================";
else{
imagePart.setBodyDevice(file);
multiPart->append(imagePart);
}
QNetworkRequest request;
request.setUrl(QUrl("https://sm.ms/api/upload"));
networkAccessManager->post(request,multiPart);
}
接下来就是处理函数:
void MainWindow::deal(QNetworkReply* reply){
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "statusCode:" << statusCode;
if(reply->error() == QNetworkReply::NoError)
{
//官方文档显示返回的reply是json格式,所以我们采用json格式读取
QByteArray allData = reply->readAll();
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(allData, &json_error));
if(json_error.error != QJsonParseError::NoError)
{
qDebug() << "json error!";
return;
}
QJsonObject rootObj = jsonDoc.object();
//我们只需要上传后的url,所以值提取了url,如果你需要其他内容,请提取方法类似
if(rootObj.contains("data"))
{
QJsonObject subObj = rootObj.value("data").toObject();
qDebug() << subObj["url"].toString();
}
}
else
{
qDebug() << "=========";
}
reply->deleteLater();
}
本文参考了:
网友评论