winhttp实现通过http的post方式上传文件并获取返回值
时间: 2023-09-29 12:11:03 浏览: 52
可以使用WinHTTP API来实现通过HTTP的POST方式上传文件并获取返回值。以下是一个简单的示例代码:
```c++
#include <Windows.h>
#include <WinHttp.h>
#include <iostream>
#pragma comment(lib, "winhttp.lib")
int main() {
// 创建WinHTTP会话句柄
HINTERNET hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
if (!hSession) {
std::cerr << "Failed to create WinHTTP session.\n";
return 1;
}
// 创建WinHTTP连接句柄
HINTERNET hConnect = WinHttpConnect(hSession, L"example.com", INTERNET_DEFAULT_HTTP_PORT, 0);
if (!hConnect) {
std::cerr << "Failed to create WinHTTP connection.\n";
WinHttpCloseHandle(hSession);
return 1;
}
// 创建WinHTTP请求句柄
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/upload", NULL, WINHTTP_NO_REFERER, NULL, 0);
if (!hRequest) {
std::cerr << "Failed to create WinHTTP request.\n";
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// 设置请求头
LPCWSTR szHeaders = L"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW";
if (!WinHttpAddRequestHeaders(hRequest, szHeaders, wcslen(szHeaders), WINHTTP_ADDREQ_FLAG_REPLACE)) {
std::cerr << "Failed to set request headers.\n";
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// 读取要上传的文件
std::ifstream file("example.txt", std::ios::binary);
if (!file) {
std::cerr << "Failed to open file.\n";
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// 获取文件长度
file.seekg(0, std::ios::end);
int fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// 构建POST数据
const char* szBoundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
std::vector<char> postData;
postData.reserve(fileSize + 1024);
postData.insert(postData.end(), szBoundary, szBoundary + strlen(szBoundary));
postData.insert(postData.end(), "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n" + 1024);
std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(postData));
postData.insert(postData.end(), "\r\n", "\r\n" + 2);
postData.insert(postData.end(), szBoundary, szBoundary + strlen(szBoundary));
postData.insert(postData.end(), "--\r\n", "--\r\n" + 4);
// 发送请求
if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, &postData[0], postData.size(), postData.size(), 0)) {
std::cerr << "Failed to send WinHTTP request.\n";
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// 接收响应
if (!WinHttpReceiveResponse(hRequest, NULL)) {
std::cerr << "Failed to receive WinHTTP response.\n";
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// 读取响应数据
std::vector<char> responseData(1024);
DWORD dwBytesRead = 0;
while (WinHttpReadData(hRequest, &responseData[0], responseData.size(), &dwBytesRead)) {
std::cout.write(&responseData[0], dwBytesRead);
}
// 关闭请求句柄、连接句柄和会话句柄
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 0;
}
```
上述代码以POST方式上传名为`example.txt`的文件到`example.com`的`/upload`路径,并输出响应数据。请根据实际情况修改代码中的URL、请求头、POST数据和文件名等参数。