用WinHttp 写一个POST访问https://sellercentral.amazon.com.au/ap/signin 自定义函数。参数有提交数据和访问头,并且返回响应内容和响应头,代码使用 Unicode 字符集
时间: 2024-01-14 16:04:45 浏览: 112
好的,以下是使用WinHttp发送POST请求的示例代码:
```c++
#include <windows.h>
#include <winhttp.h>
#include <string>
#pragma comment(lib, "winhttp.lib")
std::string UnicodeToUtf8(const wchar_t* unicode_str) {
int len = WideCharToMultiByte(CP_UTF8, 0, unicode_str, -1, nullptr, 0, nullptr, nullptr);
std::string utf8_str(len - 1, '\0');
WideCharToMultiByte(CP_UTF8, 0, unicode_str, -1, &utf8_str[0], len, nullptr, nullptr);
return utf8_str;
}
std::wstring Utf8ToUnicode(const char* utf8_str) {
int len = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, nullptr, 0);
std::wstring unicode_str(len - 1, '\0');
MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, &unicode_str[0], len);
return unicode_str;
}
bool SendHttpPostRequest(const wchar_t* url, const std::string& data, const std::wstring& headers, std::string& response_data, std::wstring& response_headers) {
HINTERNET hSession = nullptr;
HINTERNET hConnect = nullptr;
HINTERNET hRequest = nullptr;
bool result = false;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer = nullptr;
// 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, url, INTERNET_DEFAULT_HTTPS_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", nullptr, nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
// Add headers to the request.
if (hRequest)
WinHttpAddRequestHeaders(hRequest, headers.c_str(), (DWORD)-1L, WINHTTP_ADDREQ_FLAG_ADD);
// Send a request.
if (hRequest)
result = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)data.c_str(), (DWORD)data.length(), (DWORD)data.length(), 0);
// End the request.
if (result)
result = WinHttpReceiveResponse(hRequest, nullptr);
// Get the status code.
DWORD statusCode = 0;
DWORD statusCodeSize = sizeof(statusCode);
if (result)
result = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nullptr, &statusCode, &statusCodeSize, nullptr);
// Get the response headers.
std::wstring responseHeaders;
DWORD headersSize = 0;
if (result) {
result = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, nullptr, &headersSize, WINHTTP_NO_HEADER_INDEX);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
std::vector<wchar_t> headersBuffer(headersSize / sizeof(wchar_t) + 1);
if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, &headersBuffer[0], &headersSize, WINHTTP_NO_HEADER_INDEX)) {
responseHeaders = &headersBuffer[0];
}
}
}
// Get the response data.
if (result) {
do {
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
break;
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
break;
// Read the data.
ZeroMemory(pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
break;
// Append the data to the response.
response_data.append(pszOutBuffer, dwDownloaded);
// Free the memory allocated to the buffer.
delete[] pszOutBuffer;
pszOutBuffer = nullptr;
} while (dwSize > 0);
}
// Close any open handles.
if (hRequest)
WinHttpCloseHandle(hRequest);
if (hConnect)
WinHttpCloseHandle(hConnect);
if (hSession)
WinHttpCloseHandle(hSession);
response_headers = responseHeaders;
return result;
}
int wmain(int argc, wchar_t* argv[]) {
// 提交数据
std::string data = "username=test&password=test123";
// 访问头
std::wstring headers = L"Content-Type: application/x-www-form-urlencoded\r\n";
headers += L"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36\r\n";
headers += L"Accept: */*\r\n";
// 发送POST请求
std::string response_data;
std::wstring response_headers;
if (SendHttpPostRequest(L"sellercentral.amazon.com.au", data, headers, response_data, response_headers)) {
std::wprintf(L"Response headers: %s\n", response_headers.c_str());
std::printf("Response data: %s\n", response_data.c_str());
}
else {
DWORD error = GetLastError();
std::printf("Failed to send HTTP request. Error code: %u\n", error);
}
return 0;
}
```
在上面的示例代码中,我们使用了`WinHttpOpen`、`WinHttpConnect`、`WinHttpOpenRequest`、`WinHttpAddRequestHeaders`、`WinHttpSendRequest`、`WinHttpReceiveResponse`、`WinHttpQueryHeaders`和`WinHttpReadData`这些WinHttp的API来发送POST请求,并获取响应内容和响应头。其中,`UnicodeToUtf8`和`Utf8ToUnicode`是用来在Unicode和UTF-8之间进行转换的辅助函数。
阅读全文