2014-06-16 28 views
0

的一些部分我有一個返回這樣的JSON數據API的一些URL:通過WinInet的請求JSON數據複製數據

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

id應該是唯一的。

當我通過瀏覽器(Firefox或Chrome)請求該API URL時,它會返回有效數據,即每個id都是唯一的,並且非數據部分都是重複的。

但是,當我通過我自己的基於WinInet的函數請求這個API URL時,它重複了一些數據部分。它仍然是有效的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數據的某些部分,而不像普通瀏覽器?

回答

0

你需要之前將其追加空終止字節添加到szDatarecvStr,使你只追加剛接收的數據。

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

我做了你所說的。結果仍然是一樣的。 – Alexandr

+0

我剛剛意識到你根本不需要空字節,因爲你指定了'append'的第二個參數。我不確定重複是從哪裏來的。 – Barmar