You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QT/QML中XMLHttpRequest及Q_INVOKABLE调用POST请求失败问题

解决QML中POST请求分块导致服务端无法解析JSON的问题

核心原因

QML的XMLHttpRequest或通过Q_INVOKABLE调用QNetworkAccessManager时,默认会启用HTTP分块传输编码(Chunked Transfer Encoding),而你的本地服务可能未正确处理分块数据,仅读取了第一个请求包,导致遗漏后续的JSON数据。C++侧直接使用QNetworkAccessManager时,默认一次性发送完整数据,不使用分块编码,因此服务端能正常解析。

解决方案

1. 禁用QML XMLHttpRequest的分块传输

发送POST请求前,手动设置Content-Length请求头,强制禁用分块编码:

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://your-local-service-url", true);
var jsonData = JSON.stringify({key: "value"});
// 手动设置Content-Length,覆盖默认分块编码
xhr.setRequestHeader("Content-Length", jsonData.length);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(jsonData);

设置Content-Length后,QML会将数据作为完整包发送,不会拆分成Continuation包。

2. 调整C++侧封装的QNetworkAccessManager调用(若使用Q_INVOKABLE)

如果通过Q_INVOKABLE调用C++的QNetworkAccessManager,构造QNetworkRequest时需明确设置Content-Length:

Q_INVOKABLE void postRequest(const QString& url, const QString& jsonData) {
    QNetworkRequest request(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    // 手动设置Content-Length,避免分块
    request.setHeader(QNetworkRequest::ContentLengthHeader, jsonData.toUtf8().size());
    QNetworkReply* reply = networkManager->post(request, jsonData.toUtf8());
    // 后续reply处理逻辑...
}

3. 服务端兼容分块传输

若无法修改客户端代码,可在本地服务中添加分块传输处理逻辑,按照HTTP分块编码规则读取所有数据块,拼接后再解析JSON。

验证方法

修改后用WireShark抓包,确认POST请求数据包不再有Continuation标记,JSON数据完整包含在单个请求包内,数据包大小与C++侧发起的请求一致。

内容的提问来源于stack exchange,提问作者Samuel Grant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 06:09:53