Building a QT/QML application that issues GET and POST requests to a custom locally hosted service.
When the GET/POST requests are issued via C++/QNetworkAccessManager, they go through without issues. I mean that the requests hit the service, and I get a response back that is expected.
However, when issuing the requests via QML/XMLHttpRequest (or even via a Q_INVOKABLE accessible QNetworkAccessManager), the GETs 'work' ok, but the POSTs do not.
What I mean is that the POSTs fail. The service responds that there is no JSON data attached to the POST.
If I examine the HTTP packets with WireShark, I see that when initiating the calls from QML/Javascript... the GET and POST packets are sent as 'Continuation'. With the POST, the JSON data is in a later packet. When checking the same packets when the calls are initiated from C++, the packets are NOT marked as 'Continuation', and the POST packet contains all the JSON data as intended.
Also, the QML/Javascript-initiated HTTP packets are larger (4x) than the same C++-initiated packets.
C++ QNetworkAccessManager POST:
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 Packet:
XMLHttpRequest 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 Packet:
Also, as stated higher up, if I set up a Q_INVOKABLE that calls the same QNetworkAccessManager function as above from QML/Javascript... I get the same result as if I were calling XMLHttpRequest directly.
And, interestingly enough, it appears that QML XMLHttpRequest directly calls QNetworkAccessManager under the hood.
So... what gives? Why are my XMLHttpRequest packets being broken up? Yes, I tested with Firefox & Chrome, sending the exact same XMLHttpRequest and both passed without issues.
Tried C++ QNetworkAccessManager calls - Works Tried QML Javascript XMLHttpRequest calls - Fails Tried Q_INVOKABLE calls - Fails
So... long story short. Issue was because of the TOKEN. When reading it into a variable via Javascript, the EOF markers (\n\r) were included in the string. Simply using a .replace() with a regex removed them and it works now.