#include <afxinet.h>
#include <string>
using namespace std;
#define BUFFER_SIZE 1024
#define NORMAL_CONNECT INTERNET_FLAG_KEEP_CONNECTION
#define SECURE_CONNECT NORMAL_CONNECT | INTERNET_FLAG_SECURE
#define NORMAL_REQUEST INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE
#define SECURE_REQUEST NORMAL_REQUEST | INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID
// 操作成功
#define SUCCESS 0
// 操作失败
#define FAILURE 1
// 操作超时
#define OUTTIME 2
CHttpConnection *m_pConnection=NULL;
CHttpFile *m_pFile = NULL;
int ExecuteRequest_Http(LPCTSTR strMethod, LPCTSTR strUrl, CString strPostData, CString &strResponse,CString &strErrorInfo)
{
CString strServer;
CString strObject;
DWORD dwServiceType;
INTERNET_PORT nPort;
strResponse = _T("");
//Create session
CInternetSession sess;
//解析url
AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort);
//判断协议类型是否为http或https
if(AFX_INET_SERVICE_HTTP != dwServiceType && AFX_INET_SERVICE_HTTPS != dwServiceType)
{
strErrorInfo = _T("url非http或https协议!");
return FAILURE;
}
try
{
//获取 CHttpConnection*
m_pConnection = sess.GetHttpConnection(strServer,dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_CONNECT : SECURE_CONNECT,nPort);
if (m_pConnection == NULL)
{
strErrorInfo = _T("获取HttpConnection失败!");
return FAILURE;
}
//获取 CHttpFile,strMethod=_T("GET")为GET方式,strMethod=_T("POST")为POST方式
m_pFile = m_pConnection->OpenRequest(strMethod, strObject,NULL, 1, NULL, _T("HTTP/1.1"),(dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_REQUEST : SECURE_REQUEST));
if (m_pFile == NULL)
{
strErrorInfo = _T("获取HttpFile失败!");
return FAILURE;
}
m_pFile -> AddRequestHeaders( _T("Accept:application/json"));
m_pFile -> AddRequestHeaders( _T("Content-Type:application/json;charset=UTF-8"));
USES_CONVERSION;
char *pData = T2A(strPostData);
//发送请求
if(m_pFile->SendRequest(NULL, 0,pData,strlen(pData)))
{
char szChars[BUFFER_SIZE + 1] = {0};
string strRawResponse = "";
UINT nReaded = 0;
while ((nReaded = m_pFile->Read((void*)szChars, BUFFER_SIZE)) > 0)
{
//接收返回
szChars[nReaded] = '\0';
strRawResponse += szChars;
memset(szChars, 0, BUFFER_SIZE + 1);
}
//将多字符转宽字节存为 CString
int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, strRawResponse.c_str(), -1, NULL, 0);
WCHAR *pUnicode = new WCHAR[unicodeLen + 1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8,0,strRawResponse.c_str(),-1, pUnicode,unicodeLen);
CString cs(pUnicode);
delete []pUnicode;
pUnicode = NULL;
strResponse = cs;
Clear();
}
else
{
DWORD dwError = GetLastError();
strErrorInfo.Format(_T("HTTP发送请求失败,%d"),dwError);
Clear();
return FAILURE;
}
}
catch (CInternetException* e)
{
Clear();
DWORD dwErrorCode = e->m_dwError;
e->Delete();
e = NULL;
DWORD dwError = GetLastError();
strErrorInfo.Format(_T("HTTP网络异常,%d"),dwError);
if (ERROR_INTERNET_TIMEOUT == dwErrorCode)
{
return OUTTIME; //超时
}
else
{
return FAILURE; //错误
}
}
return SUCCESS; //成功
}
void Clear()
{
if(NULL != m_pFile)
{
m_pFile->Close();
delete m_pFile;
m_pFile = NULL;
}
if(NULL != m_pConnection)
{
m_pConnection->Close();
delete m_pConnection;
m_pConnection = NULL;
}
}
`
//中文 -> unicode -> utf-8(中文数据需要转换,否则会乱码)
CString UTF8_URL_ENCODE(char*Chinese)
{
CString strCode = _T("");
wchar_t unicode[128] = { 0 };
MultiByteToWideChar(CP_ACP, 0, Chinese, strlen(Chinese), unicode, 128);
unsigned char sz[128] = { 0 };
WideCharToMultiByte(CP_UTF8, 0, unicode, wcslen(unicode), (LPSTR)sz, 128, 0, 0);
string EncodeStr;
char SrcStr[128] = { 0 };
for (int i = 0; i < 128; i++)
{
if (sz[i] != NULL)
{
sprintf_s(SrcStr, "%%%X", sz[i]);
EncodeStr += SrcStr;
}
}
transform(EncodeStr.begin(), EncodeStr.end(), EncodeStr.begin(), toupper);
strCode = EncodeStr.c_str();
return strCode;
}``
通过HTTP的GET或者POST方式获取数据
于 2020-06-13 11:42:43 首次发布
本文详细介绍了使用C++进行HTTP请求的实现过程,包括创建会话、解析URL、发送GET和POST请求、处理响应及错误情况。通过具体代码示例,展示了如何利用MFC库中的CInternetSession类来实现网络请求。
2517

被折叠的 条评论
为什么被折叠?



