c++使用 WinINet 库通过 HTTP 进行连接 上传和获取数据

发布于:2024-12-07 ⋅ 阅读:(134) ⋅ 点赞:(0)

一、通过Get的方式进行获取数据

例如一个地址 http://192.168.80.112:6666/test/test/test

std::vector<CString>vAddress;

vAddress = splitAddress(ThkCabReportConfig::m_strMateraAddress);

int nres = GetMateriaInf(vAddress[1], value, vAddress[3], "GET", strJson, pMaterial, experrinf);
if (nres == -2)
	break;
int ThkCabRMaterialStaDlg::GetMateriaInf(CString lpszServerName, short port, CString lpszReqObjectName, CString strInterType, CString strJson, sThkMaterialStaTable* pMater, bool& errinf)
{
	if (pMater == nullptr)
	{
		return -1;
	}
	HINTERNET hInternet, hConnect, hRequest;
	BOOL bRet;

	hInternet = (HINTERNET)InternetOpen("User-Agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (!hInternet)
	{
		return -2;
	}

	hConnect = (HINSTANCE)InternetConnect(hInternet, lpszServerName, port, NULL, "HTTP/1.1", INTERNET_SERVICE_HTTP, 0, 0);
	if (!hInternet)
	{
		InternetCloseHandle(hInternet);
		AfxMessageBox(_T("连接接口地址失败"), MB_ICONERROR);
		return -2;
	}

 	//CString lpszReqObjectName = "datacenter/findmaterialandstock/forsk";

	CString strFormat = "?specification=%s&manufacturer=%s&qualitygrade=%s";


	CString strEncode1 = CStingToUrlEncode(pMater->m_strName);
	CString strEncode2 = CStingToUrlEncode(pMater->m_strManufacturer);
	CString strEncode3 = CStingToUrlEncode(pMater->m_strQualityGrade);
	CString strurl;
	strurl.Format(strFormat, strEncode1, strEncode2, strEncode3);
	lpszReqObjectName = lpszReqObjectName + strurl;

	hRequest = (HINTERNET)HttpOpenRequest(hConnect, strInterType, lpszReqObjectName, "HTTP/1.1", NULL, NULL, INTERNET_FLAG_RELOAD, 0);
	if (!hRequest)
	{
		InternetCloseHandle(hInternet);
		InternetCloseHandle(hConnect);
		AfxMessageBox(_T("OpenRequest失败"), MB_ICONERROR);
		return -2;
	}
	LPCSTR contentType = "Content-Type:application/json";
	bRet = HttpAddRequestHeaders(hRequest, contentType, strlen(contentType), HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);

	bRet = HttpSendRequest(hRequest, NULL, 0, NULL, 0);
	if (!bRet)
	{
		AfxMessageBox(_T("发送请求失败"), MB_ICONERROR);
		return -2;
	}
	std::string Buffer;
	while (true)
	{
		std::vector<char> vBuffer(4096);
		unsigned long bufLen = 0;
		bRet = InternetReadFile(hRequest, &vBuffer[0], 4096, &bufLen);
		if (!bRet || !bufLen)
		{
			break;
		}
		Buffer.insert(Buffer.end(), vBuffer.begin(), vBuffer.begin() + bufLen);
	}
	rapidjson::Document jsonValue;
	jsonValue.Parse(Buffer.c_str());

	if (jsonValue.IsObject())
	{
		if (jsonValue.HasMember("msg"))
		{
			ThkGlobal tglb;
			std::string msg = tglb.getLocalStr(jsonValue["msg"].GetString());
			std::string inventory = tglb.getLocalStr(jsonValue["code"].GetString());
			int nadfdf = atoi(inventory.c_str());

			if (nadfdf != 0)
			{
				if (!errinf)
				{
					AfxMessageBox(msg.c_str(), MB_ICONERROR);
					errinf = true;
				}
			}
		}
		if (jsonValue.HasMember("data"))
		{
			ThkGlobal tglb;
			const rapidjson::Value& dataObj = jsonValue["data"];
			if (dataObj.HasMember("no") && dataObj.HasMember("qty"))
			{
				std::string materialCode = tglb.getLocalStr(dataObj["no"].GetString());
				pMater->m_strCode = materialCode.c_str();

				int inventoryNum = dataObj["qty"].GetInt(); 
				pMater->m_InventoryNum = inventoryNum;
			}
		}
		
		InternetCloseHandle(hInternet);
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hRequest);
	}
	return 0;
}

通过GET方式上传数据还有中文时要进行特殊处理;

CString ThkCabRMaterialStaDlg::CStingToUrlEncode(const CString& cstr)
{
	std::string strutf8=CStringToUTF8(cstr);
	CString strUrlEncode=UrlEncode(strutf8.c_str());
	return strUrlEncode;
}

std::string ThkCabRMaterialStaDlg::CStringToUTF8(const CString& cstr)
{
	// 获取所需的 UTF-8 字符串的长度
	int size_needed = MultiByteToWideChar(CP_ACP, 0, cstr, -1, NULL, 0);
	std::wstring wideString(size_needed, 0);

	// 将多字节字符串转换为宽字符字符串
	MultiByteToWideChar(CP_ACP, 0, cstr, -1, &wideString[0], size_needed);

	// 获取 UTF-8 字符串的长度
	size_needed = WideCharToMultiByte(CP_UTF8, 0, wideString.c_str(), -1, NULL, 0, NULL, NULL);
	std::string utf8String(size_needed, 0);

	// 将宽字符字符串转换为 UTF-8
	WideCharToMultiByte(CP_UTF8, 0, wideString.c_str(), -1, &utf8String[0], size_needed, NULL, NULL);

	return utf8String;
}

CString ThkCabRMaterialStaDlg::UrlEncode(const CString& str)
{
	CString encoded;
	for (int i = 0; i < str.GetLength(); ++i) {
		TCHAR ch = str[i];
		if ((ch >= '0' && ch <= '9') ||
			(ch >= 'A' && ch <= 'Z') ||
			(ch >= 'a' && ch <= 'z') ||
			ch == '-' || ch == '_' || ch == '.' || ch == '~') {
			// 这些字符不需要编码
			encoded += ch;
		}
		else {
			// 对其他字符进行 URL 编码
			CStringA temp;
			temp.Format("%%%02X", (unsigned char)ch);
			encoded += temp;
		}
	}
	return encoded;
}

二、通过POST的方式上传一个xlsx的表格

void ThkCabWorkHStaTableDlg::OnBnClickedBtnUpLoad()
{
	std::vector<CString>vAddress;
	vAddress = splitAddress("http://192.168.80.166:6666/test/test/test");
	if ((int)vAddress.size() < 4)
		return;
	if (vAddress[1].IsEmpty())
		return;

	CString str = vAddress[2];
	std::string stdStr = CT2A(str);
	short value = 0;
	value = std::stoi(stdStr);
	CString filePath, fileName;
	CFileDialog fileDlg(TRUE);
	if (fileDlg.DoModal() == IDOK)
	{
		filePath = fileDlg.GetPathName();
		fileName = fileDlg.GetFileName();
	}
	fileDlg.m_ofn.lpstrInitialDir = ThkCabReportConfig::m_strWHExpPath; // 设置默认路径
	bool bres=UploadFile(filePath.GetString(), value, vAddress[1],vAddress[3], fileName);
	if (bres)
	{
		AfxMessageBox(_T("上传成功"), MB_OK);
	}
}
bool ThkCabWorkHStaTableDlg::UploadFile( const std::string& filePath, short port, CString lpszServerName, CString lpszReqObjectName,CString filename)
{
	HINTERNET hConnect, hRequest, hInternet;
	BOOL bRet;
	hInternet = (HINTERNET)InternetOpen("User-Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
	if (!hInternet)
	{
		return false;
	}

	 hConnect = (HINSTANCE)InternetConnect(hInternet, lpszServerName, port, NULL, "HTTP/1.1", INTERNET_SERVICE_HTTP, 0, 0);
	if (!hInternet)
	{
		InternetCloseHandle(hInternet);
		AfxMessageBox(_T("接口地址连接失败"), MB_ICONERROR);
		return false;
	}

	// Prepare the file to be uploaded
	HANDLE hFile = CreateFileA(filePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hInternet);
		return false;
	}

	DWORD fileSize = GetFileSize(hFile, NULL);
	if (fileSize == INVALID_FILE_SIZE)
	{
		CloseHandle(hFile);
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hInternet);
		return false;
	}
	// Read the file into a buffer
	char* buffer = new char[fileSize];
	DWORD bytesRead;
	if (!ReadFile(hFile, buffer, fileSize, &bytesRead, NULL) || bytesRead != fileSize)
	{
		delete[] buffer;
		CloseHandle(hFile);
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hInternet);
		AfxMessageBox(_T("读取文件失败"), MB_ICONERROR);
		return false;
	}
	 Close the file handle
	//CloseHandle(hFile);

	// Set the HTTP request headers
	const char* headers = "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW";

	std::string strfilepath=ThkCabRMaterialStaDlg::CStringToUTF8(filename);


	// Create the HTTP request
	std::string requestData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n";
	//requestData += "Content-Disposition: form-data; name=\"file\"; filename=\"" + filePath + "\"\r\n";
	requestData += "Content-Disposition: form-data; name=\"file\"; filename=\"" + strfilepath + "\"\r\n";
	requestData += "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n\r\n";
	requestData += std::string(buffer, fileSize) + "\r\n";
	requestData += "------WebKitFormBoundary7MA4YWxkTrZu0gW--\r\n";


	// Send the POST request
	DWORD bytesSent;
	 hRequest = (HINTERNET)HttpOpenRequestA(hConnect, "POST", lpszReqObjectName, "HTTP/1.1", NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
	if (!hRequest)
	{
		delete[] buffer;
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hInternet);
		AfxMessageBox(_T("OpenRequest失败"), MB_ICONERROR);
		return false;
	}

	if (!HttpSendRequestA(hRequest, headers, strlen(headers), (LPVOID)requestData.c_str(), requestData.length()))
	{
		delete[] buffer;
		InternetCloseHandle(hRequest);
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hInternet);
		AfxMessageBox(_T("发送请求失败"), MB_ICONERROR);
		return false;
	}
	std::string Buffer;
	while (true)
	{
		std::vector<char> vBuffer(4096);
		unsigned long bufLen = 0;
		 bRet = InternetReadFile(hRequest, &vBuffer[0], 4096, &bufLen);
		if (!bRet || !bufLen)
		{
			break;
		}
		Buffer.insert(Buffer.end(), vBuffer.begin(), vBuffer.begin() + bufLen);
	}
	rapidjson::Document jsonValue;
	jsonValue.Parse(Buffer.c_str());
	if (jsonValue.IsObject())
	{
		if (jsonValue.HasMember("msg"))
		{
			ThkGlobal tglb;
			std::string msg = tglb.getLocalStr(jsonValue["msg"].GetString());
			std::string inventory = tglb.getLocalStr(jsonValue["code"].GetString());
			int nadfdf = atoi(inventory.c_str());

			CString msginf="上传失败,%s";
			msginf.Format(msginf, msg.c_str());
			if (nadfdf != 0)
				AfxMessageBox(msginf, MB_ICONERROR);
			else
			{
				InternetCloseHandle(hConnect);
				InternetCloseHandle(hInternet);
				CloseHandle(hFile);
				return true;
			}	
		}
	}
	else
		AfxMessageBox(_T("返回错误,上传失败"), MB_ICONERROR);
	InternetCloseHandle(hConnect);
	InternetCloseHandle(hInternet);
	CloseHandle(hFile);
	return false;
}