四、网络请求的坑
2026/8/6大约 2 分钟
四、网络请求的坑
8. 中文歌曲名匹配失败,实际是下载文件大小为 0
现象:搜索中文歌曲名能正常显示结果,但下载后文件大小为 0,播放失败。
排查过程:
HTTP status code: 302
Content-Length header: 0
Downloaded file size: 0 bytes
Download succeeded but file is empty, removing...原因:网易云外链返回 302 重定向,QNetworkAccessManager 虽然自动跟随重定向,但某些情况下最终返回的内容为空(可能是请求头缺少 Referer 或 User-Agent)。
解决:
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0");
request.setRawHeader("Referer", "http://music.163.com/");经验:免费 API 对请求头敏感,缺少必要头信息可能导致返回空数据。
9. 302 重定向需要手动处理
现象:QNetworkAccessManager::get() 请求外链 URL,finished 信号触发后,读取到的数据为空或不是完整的 MP3。
原因:网易云返回 302 重定向,虽然 QNetworkAccessManager 默认自动跟随重定向,但某些版本或配置下可能处理不完整。
解决方案:手动检查状态码,提取 Location 头,重新发起请求。
void onReplyFinished(QNetworkReply *reply) {
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode == 302 || statusCode == 301) {
QString location = reply->rawHeader("Location");
if (!location.isEmpty()) {
// 重新发起请求
QNetworkRequest newRequest(QUrl(location));
newRequest.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0");
m_netManager->get(newRequest);
return;
}
}
// 正常处理数据...
}10. QNetworkRequest 的两种构造写法
现象:以下写法编译不通过:
QNetworkRequest requestReq(QUrl(location)); // ❌ 被解析为函数声明正确写法:
QNetworkRequest requestReq{QUrl(location)}; // ✅ C++11 统一初始化
// 或
QNetworkRequest requestReq = QNetworkRequest(QUrl(location));原因:C++ 的"最令人头痛的解析"(Most Vexing Parse),QUrl(location) 被解析为函数指针参数。使用 {} 或 = 可以避免。
11. 多次不同的 QNetworkReply 要重新建立 connect
现象:第一次下载正常,第二次下载收不到 finished 信号。
原因:QNetworkReply 对象每次请求都会重新创建,信号槽连接是针对具体对象的,不会自动转移到新对象。
解决:每次发起新请求时,重新建立连接。
void startDownload(const QString &url) {
// 创建新的 reply
m_downloadReply = m_netManager->get(QNetworkRequest(url));
// 重新连接信号(每次都要)
connect(m_downloadReply, &QNetworkReply::finished,
this, &SearchMusic::onDownloadFinished);
connect(m_downloadReply, &QNetworkReply::downloadProgress,
this, &SearchMusic::onDownloadProgress);
}经验:QNetworkReply 是单次使用的对象,每次请求都需要重新建立信号槽连接。

