通过HTTP的GET或者POST方式获取数据

本文详细介绍了使用C++进行HTTP请求的实现过程,包括创建会话、解析URL、发送GET和POST请求、处理响应及错误情况。通过具体代码示例,展示了如何利用MFC库中的CInternetSession类来实现网络请求。
#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;
}``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值