构建向自定义本地托管服务发出 GET 和 POST 请求的 QT/QML 应用程序。
当通过 C++/QNetworkAccessManager 发出 GET/POST 请求时,它们会顺利完成。我的意思是请求到达了服务,并且我得到了预期的响应。
但是,当通过 QML/XMLHttpRequest(甚至通过 Q_INVOKABLE 可访问的 QNetworkAccessManager)发出请求时,GET 可以“工作”,但 POST 则不行。
我的意思是 POST 失败。该服务响应 POST 中没有附加 JSON 数据。
如果我使用 WireShark 检查 HTTP 数据包,我会发现当从 QML/Javascript 发起调用时... GET 和 POST 数据包作为“Continuation”发送。对于 POST,JSON 数据位于稍后的数据包中。当从 C++ 发起调用时检查相同的数据包时,数据包不会被标记为“Continuation”,并且 POST 数据包包含预期的所有 JSON 数据。
此外,QML/Javascript 启动的 HTTP 数据包比相同的 C++ 启动的数据包大(4 倍)。
C++ QNetworkAccessManager 帖子:
QNetworkRequest request(url);
if (!_appendToken(request)) // <== calls setRawHeader("Authorization"...
return;
qCDebug(RESTCoTClientLog) << "_sendPostRequest" << url;
qCDebug(RESTCoTClientLog) << "_sendPostRequest" << jsonData;
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = _networkManager->post(request, jsonData);
// Connect signals and slots to handle the response
connect(reply, &QNetworkReply::finished, this, &RESTCoTClient::_onPostRequestFinished);
connect(reply, &QNetworkReply::errorOccurred, this, &RESTCoTClient::_onNetworkError);
Wireshark C++ POST 数据包:
XMLHttp请求POST:
var xhrPost = new XMLHttpRequest()
xhrPost.open("POST", url,true)
xhrPost.onreadystatechange = function () {
if (xhrPost.readyState === XMLHttpRequest.DONE) {
if (xhrPost.status === 200) {
var xhrRepsonse = xhrPost.responseText
console.log("INFO: RESTCotClient - XMLHttpRequest response => " + xhrRepsonse)
_processXhrResponse(xhrRepsonse)
} else {
console.log("ERROR: RESTCotClient - XMLHttpRequest Failed ("
+ xhrType + ") => " + xhrPost.statusText)
console.log("ERROR: RESTCotClient - XMLHttpRequest Failed ("
+ xhrType + ") => " + xhrPost.responseText)
_processXhrError()
}
}
}
var jsonData = JSON.stringify(jsonObj)
xhrPost.setRequestHeader("Content-Type", "application/json")
xhrType = "postRequest"
_appendToken(xhrPost) // <== calls setRequestHeader("Authorization"...
console.log("INFO: RESTCotClient - _sendPostRequest => " + jsonData)
xhrPost.send(jsonData)
Wireshark QML POST 数据包:
此外,如前所述,如果我设置一个 Q_INVOKABLE 来从 QML/Javascript 调用与上面相同的 QNetworkAccessManager 函数...我会得到与直接调用 XMLHttpRequest 相同的结果。
而且,有趣的是,QML XMLHttpRequest 似乎在幕后直接调用 QNetworkAccessManager。
那么...什么给出了?为什么我的 XMLHttpRequest 数据包被破坏?是的,我使用 Firefox 和 Chrome 进行了测试,发送了完全相同的 XMLHttpRequest,并且都顺利通过了。
尝试 C++ QNetworkAccessManager 调用 - 有效 尝试 QML Javascript XMLHttpRequest 调用 - 失败 尝试 Q_INVOKABLE 调用 - 失败
所以...长话短说。问题是因为令牌。当通过 Javascript 将其读入变量时,EOF 标记 ( ) 包含在字符串中。只需使用 .replace() 和正则表达式即可删除它们,现在可以使用了。