如何将CURL PUT请求转换为MFC的WebRequest实现?
把CURL PUT请求转换成MFC CHttpFile实现的分步指南
刚接触Web开发用MFC确实容易懵,我来一步步帮你把这个curl的PUT请求拆解成MFC的代码逻辑,完全不用把所有东西揉成一个字符串,拆分处理更清晰也更容易维护。
首先,我们先把curl命令里的各个部分对应到MFC的类和方法上:
curl -X PUT:指定HTTP请求方法为PUT,对应MFC里SendRequest的第一个参数(或OpenRequest时的请求方法参数)-H开头的所有项:HTTP请求头,对应CHttpFile::AddRequestHeaders方法-d后面的JSON字符串:请求体(PUT请求的核心内容),对应SendRequest的请求体参数
接下来是具体的实现步骤和代码示例:
1. 初始化网络会话与服务器连接
首先创建CInternetSession对象(这是MFC网络操作的入口),再用它建立到目标服务器的CHttpConnection:
CInternetSession session(_T("MyMFCWebRequest"), 1, INTERNET_OPEN_TYPE_PRECONFIG); CHttpConnection* pConn = nullptr; try { // 从curl的URL提取服务器地址:https://url.com -> 服务器是url.com,HTTPS默认端口443 pConn = session.GetHttpConnection(_T("url.com"), INTERNET_DEFAULT_HTTPS_PORT); } catch (CInternetException* pEx) { // 处理连接错误 TCHAR szErr[1024]; pEx->GetErrorMessage(szErr, 1024); AfxMessageBox(szErr); pEx->Delete(); session.Close(); return; }
2. 创建CHttpFile并添加请求头
接下来创建CHttpFile对象,把curl里所有-H定义的请求头逐一添加进去:
CHttpFile* pFile = nullptr; try { // URL路径是根路径"/"(因为curl的目标URL是https://url.com) pFile = pConn->OpenRequest(CHttpConnection::HTTP_VERB_PUT, _T("/"), nullptr, 1, nullptr, nullptr, INTERNET_FLAG_SECURE); // 把curl里的请求头整理成MFC字符串,每个头占一行 CString strHeaders; strHeaders += _T("apikey: MY-STAGING-KEY\r\n"); strHeaders += _T("authorization: Access-token: xx\r\n"); strHeaders += _T("cache-control: no-cache\r\n"); strHeaders += _T("content-type: application/json\r\n"); strHeaders += _T("signature: xx\r\n"); strHeaders += _T("timestamp: 1507315465\r\n"); // 注意:实际使用要动态生成当前时间戳,别写死 // 将请求头添加到CHttpFile if (!pFile->AddRequestHeaders(strHeaders)) { AfxMessageBox(_T("添加请求头失败")); goto Cleanup; } } catch (CInternetException* pEx) { TCHAR szErr[1024]; pEx->GetErrorMessage(szErr, 1024); AfxMessageBox(szErr); pEx->Delete(); goto Cleanup; }
3. 处理JSON请求体并发送PUT请求
curl里-d后的JSON就是PUT请求的内容,需要注意编码(JSON通常用UTF-8),转换后通过SendRequest发送:
// 定义JSON字符串,注意转义双引号 CStringW strJson = L"{ \"first_name\": \"Max\", \"last_name\": \"Mustermann\", \"gender\": \"m\", \"email\": \"max.mustermann@example.com\", \"phone_country_code\": \"gb\", \"phone_number\": \"11 111 111 111\", \"street\": \"Street\", \"street_number\": \"12A\", \"zipcode\": \"32112\", \"city\": \"Londong\", \"birthdate\": \"07.08\", \"note\": \"Some note\" }"; // 把宽字符JSON转成UTF-8多字节字符串(HTTP请求体标准编码) int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, strJson, -1, nullptr, 0, nullptr, nullptr); char* pUtf8Json = new char[nUtf8Len]; WideCharToMultiByte(CP_UTF8, 0, strJson, -1, pUtf8Json, nUtf8Len, nullptr, nullptr); try { // 发送请求:请求方法已在OpenRequest指定,这里传空;最后两个参数是请求体指针和长度(去掉末尾的'\0') if (!pFile->SendRequest(nullptr, 0, (LPVOID)pUtf8Json, nUtf8Len - 1)) { AfxMessageBox(_T("发送请求失败")); goto Cleanup; } // 读取响应状态与内容 DWORD dwStatusCode; pFile->QueryInfoStatusCode(dwStatusCode); if (dwStatusCode == HTTP_STATUS_OK) { CString strResponse; char szBuffer[1024]; UINT nRead; while ((nRead = pFile->Read(szBuffer, sizeof(szBuffer)-1)) > 0) { szBuffer[nRead] = '\0'; strResponse += szBuffer; } AfxMessageBox(strResponse); } else { CString strStatus; strStatus.Format(_T("请求失败,状态码:%u"), dwStatusCode); AfxMessageBox(strStatus); } } catch (CInternetException* pEx) { TCHAR szErr[1024]; pEx->GetErrorMessage(szErr, 1024); AfxMessageBox(szErr); pEx->Delete(); goto Cleanup; }
4. 资源清理(必做!)
最后别忘了释放所有创建的对象,避免内存泄漏:
Cleanup: delete[] pUtf8Json; if (pFile) { pFile->Close(); delete pFile; } if (pConn) { pConn->Close(); delete pConn; } session.Close();
几个关键注意点
- 请求方法:curl用
-X PUT指定PUT,MFC里既可以在OpenRequest时传CHttpConnection::HTTP_VERB_PUT,也可以在SendRequest第一个参数传_T("PUT") - 请求头格式:每个
-H的内容都是Key: Value格式,直接用AddRequestHeaders添加即可 - 编码问题:MFC默认是宽字符,JSON必须转成UTF-8多字节再发送,否则可能出现乱码
- 动态参数:
timestamp和signature一般是动态生成的,实际代码里别写死,要根据当前时间生成时间戳,再按接口规则生成签名
内容的提问来源于stack exchange,提问作者btec
相关产品推荐
相关产品推荐

