Запрос данных JSON через WinInet дублирует некоторые части данных

0

У меня есть URL-адрес API, который возвращает данные JSON следующим образом:

{"data":[{"id":"1","param":"value1"},{"id":"2","param":"value2"}, ... {"id":"N","param":"valueN"}]}

Каждый id должен быть уникальным.

Когда я запрашиваю этот URL-адрес API через браузер (Firefox или Chrome), он возвращает достоверные данные, т. id Каждый id уникален, а дубликаты частей данных дублируются.

Но когда я запрашиваю этот URL API через мою собственную функцию на основе WinInet он дублирует некоторые части данных. Он по-прежнему действителен JSON, но некоторые id дублируются, а некоторые из них нет. Именно так:

{"data":[{"id":"1","param":"value1"},{"id":"1","param":"value1"},{"id":"2","param":"value2"},{"id":"3","param":"value3"},{"id":"3","param":"value3"} ... {"id":"N","param":"valueN"}]}

Я использую метод GET. Вот моя функция WinInet:

using namespace std;

enum EMethod    {M_UNKNOWN, M_POST, M_GET, M_DELETE};
enum EProtocol  {P_UNKNOWN, P_HTTP, P_HTTPS};

// |example:|
/*
string responce = SendInetRequest(
    P_HTTPS, M_GET, "www.site.com", "page.php", "param1=val1&param2=val2");
*/
string SendInetRequest(const EProtocol _eProtocol, 
                        const EMethod _eMethod,
                        const string& _server,
                        const string& _page,
                        const string& _params = "")
{
    char szData[1024];
    string recvStr;

    // initialize WinInet
    HINTERNET hInternet = ::InternetOpenA("WinInet Test", 
        INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (hInternet != NULL)
    {
        INTERNET_PORT port = NULL;
        DWORD flags = NULL;

        switch (_eProtocol)
        {
        case P_HTTP:
            port = INTERNET_DEFAULT_HTTP_PORT;
            flags = /*INTERNET_FLAG_KEEP_CONNECTION*/
                INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE;
            break;
        case P_HTTPS:
            port = INTERNET_DEFAULT_HTTPS_PORT;
            flags = INTERNET_FLAG_SECURE | 
                INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE;
            break;
        default:
            return NULL;
        }

        // open HTTP session
        HINTERNET hConnect = ::InternetConnectA(hInternet, 
            _server.c_str(), port, NULL,NULL, INTERNET_SERVICE_HTTP, 0, 1);
        if (hConnect != NULL) 
        {
            string request;
            string method;
            string headers;
            string data;

            switch (_eMethod)
            {
            case M_GET:     
                method = "GET";
                request = _page + 
                    (_params.empty() ? "" : ("?" + _params));
                break;
            case M_POST:    
                method = "POST";
                request = _page;
                headers = "Content-Type: application/x-www-form-urlencoded";
                data = _params.empty() ? "" : _params;
                break;
            case M_DELETE:
                method = "DELETE";
                request = _page + 
                    (_params.empty() ? "" : ("?" + _params));
                break;
            default:        
                return NULL;
            }

            // open request
            HINTERNET hRequest = ::HttpOpenRequestA(hConnect, method.c_str(), 
                (LPCSTR)request.c_str() ,NULL, NULL, 0, flags, 1);
            if (hRequest != NULL) 
            {   
                // send request
                BOOL isSend = ::HttpSendRequestA(hRequest, headers.c_str(), 
                    headers.length(), (LPVOID)data.c_str(), data.length());

                if (isSend)
                {
                    for(;;)
                    {
                        // reading data
                        DWORD dwByteRead;
                        BOOL isRead = ::InternetReadFile(hRequest, 
                            szData, sizeof(szData) - 1, &dwByteRead);

                        // break cycle if error or end
                        if (isRead == FALSE || dwByteRead == 0)
                            break;

                        // saving result
                        recvStr.append(szData, dwByteRead);
                        szData[dwByteRead] = 0;
                    }
                }

                // close request
                ::InternetCloseHandle(hRequest);
            }
            // close session
            ::InternetCloseHandle(hConnect);
        }
        // close WinInet
        ::InternetCloseHandle(hInternet);
    }

    return recvStr;
}

Так что же не так с моей функцией? Почему он дублирует некоторые части данных JSON-ответа, в отличие от обычных браузеров?

Теги:
get
request
wininet

1 ответ

0

Вам нужно добавить байт null terminator в szData прежде чем добавлять его в recvStr, чтобы вы только добавляли только что полученные данные.

                    // saving result
                    szData[dwByteRead] = 0;
                    recvStr.append(szData, dwByteRead);
  • 0
    Я сделал то, что ты сказал. Результат все тот же.
  • 0
    Я только что понял, что вам вообще не нужен нулевой байт, так как вы указываете второй аргумент для append . Я не уверен, откуда происходит дублирование.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню