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

如何使用WinHttp获取下载文件的原始文件名与Content-Length头信息

WinHttp文件下载功能问题解决指南

1 获取响应中的原始文件名

文件原始文件名存储在响应头的Content-Disposition字段中,现有代码中给请求添加Content-Disposition头的逻辑属于多余操作,可直接删除。获取解析流程如下:

  • 调用WinHttpQueryHeaders时传入WINHTTP_QUERY_CONTENT_DISPOSITION参数获取该响应头的值
  • 解析头内容提取filename参数值,若响应未返回该头,则从请求URL的路径末尾提取文件名作为兜底方案
    代码示例:
WCHAR* pDisposition = NULL;
DWORD dwDispositionSize = 0;
// 先查询所需缓冲区大小
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_DISPOSITION, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwDispositionSize, WINHTTP_NO_HEADER_INDEX);
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
    pDisposition = new WCHAR[dwDispositionSize / sizeof(WCHAR)];
    if(WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_DISPOSITION, WINHTTP_HEADER_NAME_BY_INDEX, pDisposition, &dwDispositionSize, WINHTTP_NO_HEADER_INDEX))
    {
        std::wstring dispStr(pDisposition);
        size_t filenamePos = dispStr.find(L"filename=");
        if(filenamePos != std::wstring::npos)
        {
            std::wstring fileName = dispStr.substr(filenamePos + 9);
            // 移除文件名前后的引号
            if(fileName.front() == L'"') fileName = fileName.substr(1);
            if(fileName.back() == L'"') fileName.pop_back();
            // 此处拿到的fileName即为原始文件名,可直接传入CreateFile接口
        }
    }
    delete[] pDisposition;
}
// 兜底逻辑:无Content-Disposition头时可调用WinHttpQueryHeaders传入WINHTTP_QUERY_URL拿到请求URL,截取路径最后一段作为文件名

2 获取Content-Length字段

使用WINHTTP_QUERY_CONTENT_LENGTH参数即可获取,针对大于4G的大文件建议使用64位变量存储数值:

WCHAR* pContentLen = NULL;
DWORD dwLenSize = 0;
ULONGLONG contentLength = 0;
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwLenSize, WINHTTP_NO_HEADER_INDEX);
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
    pContentLen = new WCHAR[dwLenSize / sizeof(WCHAR)];
    if(WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, pContentLen, &dwLenSize, WINHTTP_NO_HEADER_INDEX))
    {
        contentLength = _wcstoui64(pContentLen, NULL, 10);
    }
    delete[] pContentLen;
}

3 现有代码优化点

  • 删除无效逻辑:WinHttpAddRequestHeaders添加Content-Disposition的代码、WinHttpSendRequest第二个参数传Content-Disposition的代码均无实际作用,可直接删除
  • 调整CreateFile调用时机:需在拿到原始文件名之后再调用CreateFile,不要在处理响应头之前就创建路径写死的文件
  • 补充资源释放:现有代码中获取原始响应头时分配的lpOutBuffer未释放,会造成内存泄漏

内容的提问来源于stack exchange,提问作者Nikita Pavlenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:24:04