我有一些返回JSON数据的API URL,如下所示:
{"data":[{"id":"1","param":"value1"},{"id":"2","param":"value2"}, ... {"id":"N","param":"valueN"}]}
每个id
都应该是唯一的。
当我通过浏览器(Firefox或Chrome)请求此API网址时,它会返回有效数据,即每个id
都是唯一的,而且不会复制数据部分。
但是,当我通过我自己的基于WinInet
的函数请求此API网址时,它会复制某些数据部分。它仍然是有效的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¶m2=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 :(得分:0)
您需要在之前将空终结符字节添加到szData
,然后将其附加到recvStr
,以便您只附加刚收到的数据。
// saving result
szData[dwByteRead] = 0;
recvStr.append(szData, dwByteRead);