问题描述
我需要使用C ++将json数据发布到api.在API中,我还需要包含app_id
和app_key
作为标头.下面是我正在使用的代码:
I need to post json data to api using c++. In the API, I also need to include app_id
and app_key
as header. Below is the code I am using:
std::wstring get_utf16(const std::string &str, int codepage)
{
if (str.empty()) return std::wstring();
int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
std::wstring res(sz, 0);
MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
return res;
}
LPCWSTR additionalHeaders = L"Content-Type: application/json\r\n" + L"app_id: 7ty44" + L"app_key: e36ff19de5623";
DWORD headersLength = -1;
string HttpsWebRequestPost(string domain, string url, string dat)
{
//Extra
LPSTR data = const_cast<char *>(dat.c_str());;
DWORD data_len = strlen(data);
wstring sdomain = get_utf16(domain, CP_UTF8);
wstring surl = get_utf16(url, CP_UTF8);
string response;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, sdomain.c_str(),
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", surl.c_str(),
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest(hRequest,
additionalHeaders,
headersLength,
(LPVOID)data,
data_len,
data_len,
0);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
// Keep checking for data until there is nothing left.
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
printf("Error %u in WinHttpQueryDataAvailable.\n",
GetLastError());
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize = 0;
}
else
{
// Read the data.
ZeroMemory(pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
printf("Error %u in WinHttpReadData.\n", GetLastError());
else
//printf("%s", pszOutBuffer);
response = response + string(pszOutBuffer);
// Free the memory allocated to the buffer.
delete[] pszOutBuffer;
}
} while (dwSize > 0);
}
// Report any errors.
if (!bResults)
printf("Error %d has occurred.\n", GetLastError());
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
return response;
}
我在additional headers
中包含了app_id
和app_key
,但是不确定这是否是正确的方法.另外,如何通过传递需要发送的json数据来调用它.我没有找到任何合适的例子.谢谢
I have include the app_id
and app_key
in additional headers
but not sure if this is the correct way to do it or not. Also how can I call it by passing the json data which I need to send. I did not find any good working example for this. Thanks
推荐答案
从与"S Andrew"的讨论开始,这是一个Win32控制台应用程序,使用旧的免费软件中使用的包装函数来测试WinHTTP的GET/POST.
From the discussion with "S Andrew", a Win32 Console App to test GET/POST with WinHTTP, using a wrapper function used in an old freeware
在网站 www.dummy.restapiexample.com
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <conio.h>
#include <Winhttp.h>
#pragma comment(lib, "Winhttp")
#include <Shlwapi.h> // SHRegGetValue
#pragma comment(lib, "Shlwapi")
#define HTTP_TIMEOUT 15000
HINTERNET hOpen, hOpenProxy;
void GetProxy(WCHAR* sProxyName);
DWORD WinHTTPRequest(LPCTSTR pServerName, LPCTSTR pRequest, WCHAR* sCommand, LPVOID pPostData, int nPostDataLength, LPCWSTR pwszHeaders, char **dataOut, int *nRead, WCHAR **dataHeaderOut, BOOL bTestProxy, BOOL bSecure, WCHAR* wsRedirect, DWORD *dwReturnStatus);
WCHAR g_wsCurrentProxy[255] = L"";
int main()
{
hOpen = WinHttpOpen(L"Test", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
WinHttpSetTimeouts(hOpen, HTTP_TIMEOUT, HTTP_TIMEOUT, HTTP_TIMEOUT, HTTP_TIMEOUT);
WCHAR wsHostName[MAX_PATH] = L"www.dummy.restapiexample.com";
WCHAR wsURLPathGet[MAX_PATH] = L"/api/v1/employees";
WCHAR wsURLPathPost[MAX_PATH] = L"/api/v1/create";
char sPostData[500] = "{\"name\":\"Test Unique Name 1\",\"salary\":\"123456\",\"age\":\"18\"}";
char *sHTTPData = NULL;
int nDataRead = 0;
WCHAR *wsDataHeader = NULL;
WCHAR wsRedirect[2048 + 32 + 3]; // INTERNET_MAX_URL_LENGTH
DWORD dwStatus = 0;
WCHAR wsAdditionalHeaders[1024] = L"";
lstrcpy(wsAdditionalHeaders,
L"Accept: application/json\r\n"
L"Content-Type: application/x-www-form-urlencoded\r\n"
//L"Accept-Encoding: gzip, deflate, br\r\n");
L"Accept-Encoding: txt\r\n");
printf("Before first GET - Type a key\n");
_getch();
DWORD dwReturn = WinHTTPRequest(wsHostName, wsURLPathGet, L"GET", WINHTTP_NO_REQUEST_DATA, NULL, wsAdditionalHeaders, &sHTTPData, &nDataRead, &wsDataHeader, 0, 0, wsRedirect, &dwStatus);
if (dwStatus == 0)
printf(sHTTPData);
else
printf("Error Status : [%d]\n", dwStatus);
if (sHTTPData)
delete[] sHTTPData;
if (wsDataHeader)
delete[] wsDataHeader;
printf("\n\nBefore POST - Type a key\n");
_getch();
dwReturn = WinHTTPRequest(wsHostName, wsURLPathPost, L"POST", sPostData, NULL, wsAdditionalHeaders, &sHTTPData, &nDataRead, &wsDataHeader, 0, 0, wsRedirect, &dwStatus);
if (dwStatus == 0)
printf(sHTTPData);
else
printf("Error Status : [%d]\n", dwStatus);
if (sHTTPData)
delete[] sHTTPData;
if (wsDataHeader)
delete[] wsDataHeader;
printf("\n\nBefore second GET - Type a key\n");
_getch();
dwReturn = WinHTTPRequest(wsHostName, wsURLPathGet, L"GET", WINHTTP_NO_REQUEST_DATA, NULL, wsAdditionalHeaders, &sHTTPData, &nDataRead, &wsDataHeader, 0, 0, wsRedirect, &dwStatus);
if (dwStatus == 0)
printf(sHTTPData);
else
printf("Error Status : [%d]\n", dwStatus);
if (sHTTPData)
delete[] sHTTPData;
if (wsDataHeader)
delete[] wsDataHeader;
printf("\n\nEND - Type a key\n");
_getch();
if (hOpen)
WinHttpCloseHandle(hOpen);
if (hOpenProxy)
WinHttpCloseHandle(hOpenProxy);
return 0;
}
void GetProxy(WCHAR* sProxyName)
{
lstrcpy(sProxyName, L"");
unsigned long nBufferSize = 4096;
WCHAR wszBuf[4096] = { 0 };
WINHTTP_PROXY_INFO* pInfo = (WINHTTP_PROXY_INFO*)wszBuf;
if (WinHttpQueryOption(NULL, WINHTTP_OPTION_PROXY, pInfo, &nBufferSize))
{
if (pInfo->dwAccessType == WINHTTP_OPTION_PROXY)
{
WCHAR wsKey[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
WCHAR wsValue[MAX_PATH] = L"ProxyEnable";
DWORD dwValue = (DWORD)FALSE;
DWORD dwSize = sizeof(dwValue);
LONG nStatus = SHRegGetValue(HKEY_CURRENT_USER, wsKey, wsValue, SRRF_RT_DWORD, NULL, &dwValue, &dwSize);
if ((nStatus == ERROR_FILE_NOT_FOUND) || (nStatus == ERROR_PATH_NOT_FOUND))
nStatus = SHRegGetValue(HKEY_LOCAL_MACHINE, wsKey, wsValue, SRRF_RT_DWORD, NULL, &dwValue, &dwSize);
if (nStatus != ERROR_SUCCESS)
dwValue = FALSE;
if (dwValue)
lstrcpy(sProxyName, pInfo->lpszProxy);
}
}
}
DWORD WinHTTPRequest(LPCTSTR pServerName, LPCTSTR pRequest, WCHAR* sCommand, LPVOID pPostData, int nPostDataLength, LPCWSTR pwszHeaders, char **dataOut, int *nRead, WCHAR **dataHeaderOut, BOOL bTestProxy, BOOL bSecure, WCHAR* wsRedirect, DWORD *dwReturnStatus)
{
HINTERNET hCurrentOpen = NULL;
if (bTestProxy)
{
WCHAR sProxy[255] = L"";
GetProxy(sProxy);
if (lstrcmp(sProxy, L"") == 0)
hCurrentOpen = hOpen;
else if (lstrcmp(sProxy, g_wsCurrentProxy) != 0)
{
if (hOpenProxy)
WinHttpCloseHandle(hOpenProxy);
hOpenProxy = WinHttpOpen(L"Test", WINHTTP_ACCESS_TYPE_NAMED_PROXY, sProxy, NULL, 0/*INTERNET_FLAG_ASYNC*/);
lstrcpy(g_wsCurrentProxy, sProxy);
hCurrentOpen = hOpenProxy;
}
else
hCurrentOpen = hOpenProxy;
}
else
hCurrentOpen = hOpen;
HINTERNET hConnect = NULL;
if (bSecure)
hConnect = WinHttpConnect(hCurrentOpen, pServerName, INTERNET_DEFAULT_HTTPS_PORT, 0);
else
hConnect = WinHttpConnect(hCurrentOpen, pServerName, INTERNET_DEFAULT_HTTP_PORT, 0);
if (!hConnect)
{
DWORD dwError = GetLastError();
return dwError;
}
DWORD dwFlags;
if (bSecure)
dwFlags = WINHTTP_FLAG_SECURE | WINHTTP_FLAG_REFRESH;
else
dwFlags = WINHTTP_FLAG_REFRESH;
HINTERNET hRequest = WinHttpOpenRequest(hConnect, sCommand, pRequest, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, dwFlags);
if (!hRequest)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
return dwError;
}
WinHttpAddRequestHeaders(hRequest, pwszHeaders, -1, WINHTTP_ADDREQ_FLAG_ADD);
int nLengthPostData;
if (nPostDataLength == NULL)
{
if (pPostData)
nLengthPostData = strlen((char*)pPostData);
else
nLengthPostData = 0;
}
else
nLengthPostData = nPostDataLength;
BOOL bSuccess;
if (wsRedirect != NULL)
{
DWORD dwOption;
DWORD dwOptionSize;
dwOption = WINHTTP_OPTION_REDIRECT_POLICY_NEVER;
dwOptionSize = sizeof(DWORD);
bSuccess = WinHttpSetOption(hRequest, WINHTTP_OPTION_REDIRECT_POLICY, (LPVOID)&dwOption, dwOptionSize);
DWORD dwOptionValue = WINHTTP_DISABLE_REDIRECTS;
bSuccess = WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwOptionValue, sizeof(dwOptionValue));
}
BOOL b = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, pPostData, pPostData == NULL ? 0 : nLengthPostData, nLengthPostData, 0 );
if (!b)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return dwError;
}
WinHttpReceiveResponse( hRequest, NULL);
DWORD dwStatus = 0;
DWORD dwStatusSize = sizeof(DWORD);
if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatus, &dwStatusSize, NULL))
{
if (HTTP_STATUS_REDIRECT == dwStatus || HTTP_STATUS_MOVED == dwStatus)
{
DWORD dwSize;
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return 500;
LPWSTR pwsRedirectURL = new WCHAR[dwSize];
bSuccess = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, pwsRedirectURL, &dwSize, WINHTTP_NO_HEADER_INDEX);
if (!bSuccess)
return 500;
if (wsRedirect != NULL)
lstrcpy(wsRedirect, pwsRedirectURL);
if (dwReturnStatus != NULL)
*dwReturnStatus = dwStatus;
delete[] pwsRedirectURL;
}
else if (dwStatus != HTTP_STATUS_OK && dwStatus != HTTP_STATUS_BAD_REQUEST && dwStatus != HTTP_STATUS_CREATED)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
if (dwReturnStatus != NULL)
*dwReturnStatus = dwStatus;
return dwError;
}
}
if (dataHeaderOut != NULL)
{
DWORD dwSize = 0;
WCHAR *pOutBuffer = NULL;
if (!WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX))
{
DWORD dwErr = GetLastError();
if (dwErr != ERROR_INSUFFICIENT_BUFFER)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return dwError;
}
}
pOutBuffer = new WCHAR[dwSize];
if (WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF,WINHTTP_HEADER_NAME_BY_INDEX, pOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX))
{
pOutBuffer[dwSize] = '\0';
*dataHeaderOut = (WCHAR*)pOutBuffer;
}
//delete[] pOutBuffer;
}
char *sReadBuffer = NULL;
DWORD nTotalRead = 0;
DWORD nToRead = 0;
DWORD nBytesRead = 0;
do {
if (!WinHttpQueryDataAvailable(hRequest, &nToRead))
break;
if (nToRead == 0)
break;
sReadBuffer = (char*)((sReadBuffer == NULL) ? malloc(nToRead) : realloc(sReadBuffer, nTotalRead + nToRead + 1));
if (WinHttpReadData(hRequest, sReadBuffer + nTotalRead, nToRead, &nBytesRead))
{
nTotalRead += nBytesRead;
}
} while (nToRead > 0);
if (sReadBuffer != NULL && nTotalRead > 0)
{
{
char *sBuffer = new char[nTotalRead + 1];
memcpy(sBuffer, sReadBuffer, nTotalRead + 1);
sBuffer[nTotalRead] = '\0';
*dataOut = sBuffer;
}
free(sReadBuffer);
}
*nRead = nTotalRead;
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return ERROR_SUCCESS;
}
这篇关于如何在C ++中使用Winhttp将JSON数据发布到api的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!