一、Get 和 POST 方法的区别
Http 协议与服务器交互,最基本 4 种方法:GET、POST、PUT、DELETE,对应着这个资源的查、改、增、删 4 个操作。
GET 一般用于获取/查询资源信息,而 POST 一般用于更新资源信息
区别:
- GET 提交的数据会放在 URL 之后,以 ?分割 URL 和传输数据,参数之间以 & 相连,如 EditPosts.aspx?name=text1&id=12345;而 POST 方法是把提交的数据放在 HTTP 包的 Body中
- GET 提交的数据大小有限制(因为浏览器对 URL 的长度有限制),而 POST 方法提交的数据没有限制
- GET 方式需要使用 Request.QueryString 来取得变量的值,而 POST 方式通过 Request.Form 来获取变量的值
- GET 方式提交数据,会带来安全问题,比如一个登陆页面,通过 GET 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码
总结:
较大量的数据 – 用 post (数据放在 http 包的 Body 中)
少量的数据 – 用 get (数据放在 URL 后)
二、使用 POST 发送数据
主要是为了向服务器发送 较大量 的客户端的数据,不受 URL 的长度限制
post 请求将数据以 URL 编码的形式放在 HTTP 正文中,字段形式为 fieldname=value,用 & 分隔每个字段
- 少量数据 - 一次 post
Content-Type : application/x-www-form-urlencoded
调用
Http * m_http = new Http();
QByteArray retData = "";
bool bl = m_http->post(uploadUrl, "", retData, token);
bool Http::post(const QString url,const QString data, QByteArray &ret, const QString token)
{
QNetworkAccessManager *manager = new QNetworkAccessManager;
QNetworkReply *reply;
QNetworkRequest u = QNetworkRequest(QUrl(url));
u.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-Form-urlencoded");
QByteArray dataa = data.toUtf8();
if (token != "")
{
u.setRawHeader("x-authentication-token", token.toLatin1());
}
u.setHeader(QNetworkRequest::ContentLengthHeader, dataa.length());
reply = manager->post(u, dataa);
QEventLoop loop; // 使用事件循环使得网络通讯同步进行
QTimer::singleShot(6000, &loop, SLOT(quit()));
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec(); // 进入事件循环, 直到reply的finished()信号发出, 这个语句才能 //退出
if (reply->error())
{
ret = reply->errorString().toLatin1();
delete manager;
return false;
}
if (reply->isFinished()) {
ret = reply->readAll();
delete manager;
return true;
}
else {
delete manager;
return false;
}
}
- 大量数据 - 一次 post - 使用 multipart
使用属性 “Content-Type”=“multipart/form-data; boundary=ABCD” ,post 一次
调用
Http * m_http = new Http();
QString resultStr = "";
QString m_uploadFileUrl= "对方 URL 路径";
QString path= "D://A.jpg";
m_http->uploadFile(m_uploadFileUrl, path, "pic", resultStr)
bool Http::uploadFile(const QString url, const QString path, const QString param,QString &resultStr)
{
QString absultePath = path;
QFile file(absultePath);
if (!file.exists())
{
resultStr = "filepath not exists";
return false;
}
if (!file.open(QIODevice::ReadOnly))
{
resultStr = "open file failed";
return false;
}
QFileInfo fi(absultePath);
QNetworkAccessManager *accessManager = new QNetworkAccessManager(this);
QNetworkReply *reply;
accessManager->setNetworkAccessible(QNetworkAccessManager::Accessible);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
// dat 文件;
if ("dat" == param)
{
QHttpPart datPart;
datPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
QString contentDis = tr("form-data; name=\"file\"; filename=\"%1\"").arg(fi.fileName());
datPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentDis));
datPart.setBody(file.readAll());
file.setParent(multiPart);
multiPart->append(datPart);
}
// 图片文件;
else
{
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
QString contentDis = tr("form-data; name=\"file\"; filename=\"%1\"").arg(fi.fileName());
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentDis));
imagePart.setBody(file.readAll());
file.setParent(multiPart);
multiPart->append(imagePart);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"modelImg\""));
textPart.setBody("img");
multiPart->append(textPart);
}
multiPart->setBoundary("-----WebKitFormBoundaryE19zNvXGzXaLvS5C");
QUrl gurl(url);
QNetworkRequest request(gurl);
reply = accessManager->post(request, multiPart);
bool bl = false;
QEventLoop loop;
//QTimer::singleShot(40000, &loop, SLOT(quit()));
connect(accessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
loop.exec();
if (reply->error() == QNetworkReply::NoError)
{
QByteArray jpegData = reply->readAll();
resultStr = ((QString)jpegData).toUtf8();
reply->deleteLater();
QJsonParseError parse_error;
const QJsonDocument &parse_doc = QJsonDocument::fromJson(jpegData, &parse_error);
if (parse_error.error == QJsonParseError::NoError)
{
const QJsonObject &object = parse_doc.object();
int status = object.value(QStringLiteral("errorCode")).toInt();
if (0 == status)
{
bl = true;
qDebug() << "upload success";
}
else
{
qDebug() << "upload fail";
resultStr = object.value(QStringLiteral("message")).toString();
}
}
else
{
resultStr = QStringLiteral("data not json[") + jpegData;
}
}
else
{
qDebug() << "uploadfile error " << reply->error() << reply->errorString();
resultStr = reply->errorString();
reply->deleteLater();
}
delete accessManager;
return bl;
}
- 大量数据 - 多次 post
采用 每 4k 的数据 post 一次,多次 post 操作
Http * m_http = new Http();
QString resultStr = "";
QString m_uploadFileUrl= "对方 URL 路径";
QString path= "D://A.dat";
m_http->uploadFile(m_uploadFileUrl, path, "", resultStr)
bool Http::uploadFile(const QString url, const QString path, const QString param,QString &error)
{
QString absultePath = path;
QFile file(absultePath);
if (!file.exists()) {
error = "filepath not exists";
return false;
}
if (!file.open(QIODevice::ReadOnly)) {
error = "open file failed";
return false;
}
qint64 length = file.size();
QNetworkAccessManager *accessManager = new QNetworkAccessManager(this);
QNetworkReply *reply;
accessManager->setNetworkAccessible(QNetworkAccessManager::Accessible);
QUrl gurl(url);
QNetworkRequest request(gurl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
request.setHeader(QNetworkRequest::ContentLengthHeader, length);
bool bl = false;
int64_t pos = 0;// reqUploadPostion(md5, length);
int64_t postion = pos;
request.setHeader(QNetworkRequest::LocationHeader, postion);
while (!file.atEnd())
{
file.seek(postion);
char *byte = new char[1 * 1024 * 1024];
if (postion + 1 * 1024 * 1024 < length)
{
qint64 result = file.read(byte, 1 * 1024 * 1024);
qDebug() << "uploadFile read=" << result;
QByteArray arrByte(byte, 1 * 1024 * 1024);
arrByte.size();
request.setHeader(QNetworkRequest::LocationHeader, postion);
reply = accessManager->post(request, arrByte);
postion += 1 * 1024 * 1024;
}
else
{
const int left = length - postion;
qint64 result = file.read(byte, left);
qDebug() << result;
QByteArray arrByte(byte, left);
arrByte.size();
request.setHeader(QNetworkRequest::LocationHeader, postion);
reply = accessManager->post(request, arrByte);
postion += left;
}
delete[]byte;
QEventLoop loop;
//QTimer::singleShot(40000, &loop, SLOT(quit()));
connect(accessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
loop.exec();
if (reply->error() == QNetworkReply::NoError)
{
QByteArray jpegData = reply->readAll();
reply->deleteLater();
QJsonParseError parse_error;
const QJsonDocument &parse_doc = QJsonDocument::fromJson(jpegData, &parse_error);
if (parse_error.error == QJsonParseError::NoError)
{
const QJsonObject &object = parse_doc.object();
int status = object.value(QStringLiteral("status")).toInt();
QString msg = object.value(QStringLiteral("msg")).toString();
}
else {
error = QStringLiteral("data not json[")+ jpegData;
}
}
else
{
qDebug() << "uploadfile error " << reply->error() << reply->errorString();
error = reply->errorString();
reply->deleteLater();
break;
}
}
delete accessManager;
return bl;
}
三、使用 GET 发送数据
调用
QByteArray retData = "";
m_http->get(m_urlSendcode + QString("?phone=%1").arg(phoneCode), retData);
bool Http::get(QString url, QByteArray& ret)
{
QNetworkAccessManager *manager = new QNetworkAccessManager;
QNetworkReply *reply;
QNetworkRequest u = QNetworkRequest(QUrl(url));
//u.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-Form-urlencoded");
reply = manager->get(u);
QEventLoop loop; // 使用事件循环使得网络通讯同步进行
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
QTimer::singleShot(6000, &loop, SLOT(quit()));
loop.exec(); // 进入事件循环, 直到reply的finished()信号发出, 这个语句才能 //退出
if (reply->error())
{
ret = reply->errorString().toLatin1();
delete manager;
return false;
}
if (reply->isFinished()) {
ret = reply->readAll();
delete manager;
return true;
}
else {
delete manager;
return false;
}
}