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

C++使用WinInet获取网络JSON响应的代码修正方案

核心错误说明

你的代码无法正常请求的核心原因是WinINet系列API参数传参错误,同时存在响应读取不全、资源泄漏、请求协议不匹配的问题:

  • InternetConnect第二个参数仅接收服务器域名/IP,不能传入完整URL,传入全路径会导致无法连接到正确服务
  • HttpOpenRequest第三个参数接收请求的资源相对路径,传入完整URL会导致请求路径非法
  • 未做任何API调用返回值校验,请求出错时无法定位问题,还会执行后续无效逻辑
  • 仅调用一次InternetQueryDataAvailable+单次读取无法拿到完整响应,数据长度不准时会出现JSON截断
  • 动态申请的缓冲区未释放,存在内存泄漏
  • 使用HTTP协议请求时,当前ip-api接口默认会跳转HTTPS,会导致请求失败
  • GET请求不需要添加Content-Type: application/json头,多余头可能触发服务端拦截
前置依赖

编译前请在代码开头引入WinINet相关依赖:

#include <windows.h>
#include <wininet.h>
#include <string>
#pragma comment(lib, "wininet.lib")
using namespace std;
修正后代码
string GetLocation() {
    DWORD wrt = 0;
    LPCWSTR userAgent = L"SimpleLocationClient";
    string response;

    // 按WinINet要求拆分服务器地址和请求路径
    LPCWSTR server = L"ip-api.com";
    LPCWSTR path = L"/json/168.197.155.244";

    // 初始化网络会话
    HINTERNET hSession = InternetOpen(userAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (!hSession) return "";

    // 建立HTTPS连接,使用默认443端口
    HINTERNET hConnect = InternetConnect(hSession, server, INTERNET_DEFAULT_HTTPS_PORT, 
        NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if (!hConnect) {
        InternetCloseHandle(hSession);
        return "";
    }

    // 创建GET请求,添加HTTPS安全标志
    HINTERNET hRequest = HttpOpenRequest(hConnect, L"GET", path, NULL, NULL, NULL,
        INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD, 0);
    if (!hRequest) {
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
        return "";
    }

    // 发送请求
    if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) {
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
        return "";
    }

    // 循环读取完整响应,避免截断
    const int BUF_SIZE = 4096;
    char buf[BUF_SIZE];
    while (true) {
        memset(buf, 0, BUF_SIZE);
        BOOL readRes = InternetReadFile(hRequest, buf, BUF_SIZE - 1, &wrt);
        if (!readRes || wrt == 0) break;
        response.append(buf, wrt);
    }

    // 按顺序关闭所有句柄释放资源
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    return response;
}
关键修改点
  • 拆分服务器地址和请求路径,匹配WinINet的参数要求
  • 切换为HTTPS协议,添加对应安全标志和默认端口,避免跳转拦截
  • 移除GET请求不需要的多余请求头
  • 增加每一步API调用的返回值校验,出错时提前退出并释放已申请资源
  • 用固定缓冲区循环读取响应,保证能拿到完整JSON数据
  • 去掉无意义的动态内存申请,避免内存泄漏
  • 调整句柄关闭顺序,所有异常分支都能正确释放资源

内容的提问来源于stack exchange,提问作者Antony Lucas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:42:24