【问题标题】:QNetworkRequest returning nullQNetworkRequest 返回 null
【发布时间】:2019-05-04 01:25:48
【问题描述】:

我必须使用发布到 google 脚本(见下文),我希望在脚本结束时收到反馈,表明一切正常。

function doPost(e){
   var idm = e.parameter.idm;
   var sheet_purchaseHistory = SpreadsheetApp.getActive().getSheetByName('purchaseHistory');
   var date = new Date();
   var time = Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');
   sheet_purchaseHistory.getRange(sheet_purchaseHistory.getLastRow()+1, 1).setValue(time);
   sheet_purchaseHistory.getRange(sheet_purchaseHistory.getLastRow(), 2).setValue(mailadress);
   return ContentService.createTextOutput(JSON.stringify({'status': 'success'})).setMimeType(ContentService.MimeType.JSON);
}

在我的 cpp 代码中,我有:

标题 (.h)

QNetworkRequest request;
QNetworkAccessManager *manager;
QByteArray ba;
QNetworkReply* reply;

构造函数:

manager = new QNetworkAccessManager(this);  // I tried with and without parsing the (this)
request.setUrl(QUrl("https://script.google.com/macros/s/AKfycbzhHBpZ8jMfa2bwE_A0lQJNqOzVl894dcjkch_-0mNC6EX9usn1/exec"));

函数内部:

manager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QUrlQuery postData;
postData.addQueryItem("idm", "string");
QNetworkReply *rp = manager->post(request,postData.toString(QUrl::FullyEncoded).toUtf8());
QEventLoop loop;
connect(rp, SIGNAL(finished()), &loop, SLOT(quit())); //readready SIGNAL also tried
loop.exec();
QByteArray data = rp->readAll();
QString dataReply(data);
qDebug() << dataReply;

发生的情况是我总是收到 null。我已经尝试了几种组合,例如不同的信号(readyread、finished...),使用 QUrlQuery 和 ByteArray,设置不同的标题,但没有成功。

我还注意到,当我的参数在我的请求 (https://address?parameters=string) 中时,我可以收到返回。 (在这种情况下,通过从“postdate”中删除参数并将它们包含在 post“req”中

QNetworkReply *rep = man->post(req,postdata);

RESTESTTEST 的打印:我尝试使用https://resttesttest.com/ 发布并且它工作正常。它给出了以下 cmets

有人可以帮帮我吗?

【问题讨论】:

  • 除了resttesttest.com的测试图像之外,您还可以提供url等来测试您的问题
  • 我刚刚更新了帖子! :-)
  • 你改变了结果吗?以前,你是 {"okay": value} 现在它是 "OK"

标签: c++ qt post qnetworkaccessmanager qnetworkreply


【解决方案1】:

在使用 curl 的以下命令的帮助下,我能够分析请求:

curl  --trace-ascii  output.txt \
      -d "idm=0123" \
      -L "https://script.google.com/macros/s/AKfycbzhHBpZ8jMfa2bwE_A0lQJNqOzVl894dcjkch_-0mNC6EX9usn1/exec" 

.txt 文件中有以下行:

# ...
== Info: Issue another request to this URL: 'https://script.googleusercontent.com/macros/echo?user_content_key=odFvp9PfkjN-H6-IhBUWhj1XC4LbgGXq3moew78NtUkeQAI4UCwjEaz33jH1p_VSrMLvl9R-1p2f-LCuIURpcA9ynEuB76Kdm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnDmqvNuuY9_pIuNLYjrNDt9AJiVy2Q9_jt9ucsQKYIYmzKj2_WuA-BZmfTxlnQZT_cbqvF_hZXXo&lib=MbJJIMSCHwBgrN--y_1G9PbYl-ov70HvX'
== Info: Switch from POST to GET
# ...

这告诉我们重定向从 POST 更改为 GET,因此不会考虑继续尝试 POST 的属性QNetworkRequest::NoLessSafeRedirectPolicy。所以解决办法是手动处理重定向。

QNetworkAccessManager manager;

QNetworkRequest request;
QUrl url("https://script.google.com/macros/s/AKfycbzhHBpZ8jMfa2bwE_A0lQJNqOzVl894dcjkch_-0mNC6EX9usn1/exec");
request.setUrl(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QUrlQuery postData;
postData.addQueryItem("idm", "string");
QNetworkReply *reply_post = manager.post(request,  postData.toString(QUrl::FullyEncoded).toUtf8());
QEventLoop loop;
QObject::connect(reply_post, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();

QNetworkRequest redirect_request;
redirect_request.setUrl(reply_post->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl());
reply_post->deleteLater();
QNetworkReply *reply_get = manager.get(redirect_request);
QObject::connect(reply_get, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
qDebug()<< reply_get->readAll();
reply_get->deleteLater();

输出:

OK

【讨论】:

  • 感谢您的回复!实际上我需要数据(我的意思是 postData 中的参数)。当我将其包括在内时,即使包括您的建议,我也不会收到回报。有什么方法可以强制需要该属性吗?亲切的问候,
  • 不,我不同意!我的 API 中有一个 [...],我说它与数据一起使用(我现在插入了此代码)由于这是我的系统的注册,我有点不愿意让它可用。另外,我提出了我最初的问题,“当我的参数在我的请求中时,我可以收到返回”,所以到目前为止你所做的是像我一样删除参数......我还不知道值将您的回答标记为正确,但对我来说,这与我之前描述的情况相同......
  • 如果您输入所描述的参数(如我发送的图像中所示),它可以工作。
  • 是的。我还没有专注于那个,因为我/不确定这是否会起作用。无论如何,我刚刚添加::-) return ContentService.createTextOutput(JSON.stringify({'okay': idm})).setMimeType(ContentService.MimeType.JSON);请注意我所说的问题是:“当我的参数在我的请求中时,我可以收到返回。” (我这里没有说不发送参数会报错,我说放在postdata中返回null)所以我需要在合适的地方接收返回发送参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 2020-06-19
  • 2011-10-15
相关资源
最近更新 更多