IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++如何使用libcurl发送post请求的三种content-type的封装 -> 正文阅读

[C++知识库]C++如何使用libcurl发送post请求的三种content-type的封装

作者:虚坏叔叔
博客:https://xuhss.com

早餐店不会开到晚上,想吃的人早就来了!😄

C++如何使用libcurl发送post请求的三种content-type的封装

C++如何使用libcurl发送post请求的3中content-type的封装。

我们知道http协议的post请求的content-type有三种方式,其他语言都能很方便的设置,那么c++如何实现post请求不同content-type的请求能,下面封装好了大家需要可以直接拿

里面用到的json库可以参照这篇文章C++ Json解析库CJsonObject的详细使用(跨平台无须编译成库)

一、以下是封装好的http请求类(get/post)

下面封装了http请求工具类,在外部直接调用此类即可

HttpLink.h

//********************************************************************
//    
//    @copyright      www.xuhss.com
//    @version        v1.0
//    @file           www.xuhss.com
//    @author         w
//    @date           202/1/21 15:01
//    @brief          连接服务端
//*********************************************************************

#pragma once

#include "..\..\..\ThridLibrary\curl-7.62.0\include\curl\curl.h"
#pragma comment(lib, "libcurl.lib")

class CHttpLink
{
public:
	CHttpLink();
	~CHttpLink();

	/**
	*  @brief    使用Post 用http连接服务端
	*
	*  @param    const std::string &url	网址
	*  @param    const std::string &postParams	param参数
	*  @param    int nPort	端口
	*  @param    std::string &strResponse	返回值
	*  @param    std::list<std::string> listRequestHeader	请求头
	*  @param    bool bResponseIsWithHeaderData	是否带请求头
	*  @param    int nConnectTimeout
	*  @param    int nTimeout
	*  @return   CURLcode
	*/
	CURLcode CurlPostRequst(const std::string &url, const std::string &strParams, int nPort, 
		std::string &strResponse, std::list<std::string> listRequestHeader,
		bool bResponseIsWithHeaderData = false, int nConnectTimeout = 10, int nTimeout = 10);

	/**
	*  @brief    使用Post 用http连接服务端
	*
	*  @param    const std::string &url	网址
	*  @param    std::string &strResponse	返回值
	*  @param    int nPort	端口
	*  @param    std::list<std::string> listRequestHeader	请求头
	*  @param    bool bResponseIsWithHeaderData	是否带请求头
	*  @param    int nConnectTimeout
	*  @param    int nTimeout
	*  @return   CURLcode
	*/
	CURLcode CurlGetRequst(const std::string &url, std::string &strResponse,
		int nPort, std::list<std::string> listRequestHeader,
		bool bResponseIsWithHeaderData = false, int nConnectTimeout = 10, int nTimeout = 10);
};


HttpLink.cpp

#include "StdAfx.h"
#include "HttpLink.h"


CHttpLink::CHttpLink()
{
}


CHttpLink::~CHttpLink()
{
}

size_t WriteData(void *buffer, size_t size, size_t nmemb, void *userp)
{
	std::string* str = dynamic_cast<std::string*>((std::string *)userp);
	if (NULL == str || NULL == buffer)
	{
		return -1;
	}

	char* pData = (char*)buffer;
	str->append(pData, size * nmemb);
	return nmemb;
}

CURLcode CHttpLink::CurlPostRequst(const std::string &url, const std::string &strParams, int nPort,
	std::string &strResponse, std::list<std::string> listRequestHeader,
	bool bResponseIsWithHeaderData/* = false*/, int nConnectTimeout/* = 10*/, int nTimeout/* = 10*/)
{
	// 初始化  
	CURL *curl = curl_easy_init();
	struct curl_httppost* post = NULL;
	struct curl_httppost* last = NULL;

	// 返回值
	CURLcode res;
	if (curl)
	{
		// set params  
		// 1为Post,0为Get方式  
		curl_easy_setopt(curl, CURLOPT_POST, 1); 

		// 设置网址
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // url  

		// 设置端口
		curl_easy_setopt(curl, CURLOPT_PORT, nPort);    //port

		//构建HTTP报文头
		struct curl_slist* headers = NULL;
		if (listRequestHeader.size() > 0)
		{
			std::list<std::string>::iterator iter, iterEnd;
			iter = listRequestHeader.begin();
			iterEnd = listRequestHeader.end();
			for (iter; iter != iterEnd; iter++)
			{
				headers = curl_slist_append(headers, iter->c_str());
			}
			if (headers != NULL)
			{
				//设置http请求头信息
				curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
			}
		}
		else
		{
			headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded");
			if (headers != NULL)
			{
				//设置http请求头信息
				curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
			}
		}

		// 设置param参数
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strParams.c_str()); 

		// 构造post参数 (表单的形式)
//		curl_formadd(&post, &last, CURLFORM_PTRNAME, "materialistid{}", CURLFORM_PTRCONTENTS, strParams, CURLFORM_END);
//		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);                     

		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //返回的头部中有Location(一般直接请求的url没找到),则继续请求Location对应的数据 
		curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);

		// 回调函数
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);

		// 获取返回数据
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

		//响应体中是否包含了头信息
		if (bResponseIsWithHeaderData)
		{
			curl_easy_setopt(curl, CURLOPT_HEADER, 1);
		}
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nConnectTimeout);
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeout);
		
		// 开始连接
		res = curl_easy_perform(curl);
		if (headers != NULL)
		{
			curl_slist_free_all(headers); //free the list again
		}
	}
	
	//清理
	curl_easy_cleanup(curl);
	return res;
}

CURLcode CHttpLink::CurlGetRequst(const std::string &url, std::string &strResponse,
	int nPort, std::list<std::string> listRequestHeader,
	bool bResponseIsWithHeaderData/* = false*/, int nConnectTimeout/* = 10*/, int nTimeout/* = 10*/)
{
	// init curl  
	CURL *curl = curl_easy_init();
	// res code  
	CURLcode res;
	if (curl)
	{
		// set params  
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // url  
		curl_easy_setopt(curl, CURLOPT_PORT, 18080);    //port
		curl_easy_setopt(curl, CURLOPT_POST, 0); // get reqest 
	//构建HTTP报文头
		struct curl_slist* headers = NULL;
		if (listRequestHeader.size() > 0)
		{
			std::list<std::string>::iterator iter, iterEnd;
			iter = listRequestHeader.begin();
			iterEnd = listRequestHeader.end();
			for (iter; iter != iterEnd; iter++)
			{
				headers = curl_slist_append(headers, iter->c_str());
			}
			//headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
				//headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded");
			if (headers != NULL)
			{
				curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);//设置http请求头信息
			}
		}
//		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); // if want to use https  
//		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); // set peer and host verify false  
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
		curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
		if (bResponseIsWithHeaderData)
		{
			curl_easy_setopt(curl, CURLOPT_HEADER, 1);//响应体中是否包含了头信息,比如Content-Type:application/json;charset=UTF-8
		}
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nConnectTimeout); // set transport and time out time  
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeout);
		// start request  
		res = curl_easy_perform(curl);
		if (headers != NULL)
		{
			curl_slist_free_all(headers); //free the list again
		}
	}
	// release curl  
	curl_easy_cleanup(curl);
	return res;
}

二、调用HttpLink post的三种content-type

2.1 Content-Type:application/x-www-form-urlencoded

	std::string strUser, strPass;
	strUser = CT2A(strUserName.GetBuffer());
	strPass = CT2A(strPossWord.GetBuffer());
	strUserName.ReleaseBuffer();
	strPossWord.ReleaseBuffer();
	std::string strLoginParam = "username=";
	strLoginParam += strUser;
	strLoginParam += "&password=";
	strLoginParam += strPass;

	std::string strResponse;
	std::list<std::string> listRequestHeader;
	listRequestHeader.push_back("Content-Type:application/x-www-form-urlencoded");

	CHttpLink httpLink;
	httpLink.CurlPostRequst(_strURL, strLoginParam, _nPort, strResponse, listRequestHeader, true);

	// 从返回值中截取token值
	std::string strError = GetTokenFromStr(strResponse, _strToken);
	if (!strError.empty())
	{
		CString strWError = strError.c_str();
		MessageBox(strWError, _T("提示"), MB_OK | MB_ICONINFORMATION);
		return;
	}
	else
	{

	}

2.2 Content-Type:application/json;charset=UTF-8

	// 构建json数据作为param传递
	cJSON *pJson = cJSON_CreateObject();

	//创建一个整型数组
	cJSON *pIntArr = cJSON_CreateArray();

	cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
	int nCount = (int)nArr.size();
	for (int i = 0; a && i<nCount; i++)
	{
		n = cJSON_CreateDouble((long double)((unsigned int)nArr[i]), 1);
		//n = cJSON_CreateNumber(nArr[i]);
		if (!i)
			a->child = n;
		else
		{
			p->next = n;
			n->prev = p;
		}
		p = n;
	}

	cJSON_AddItemToObject(pJson, "materialistid", a);
	char *json_data = cJSON_Print(pJson);

	// 构建网址
	std::string strRespose;
	std::string strUrl = BuildUrl(_strIP, _strPort, _strPrefix, _strController);

	std::list<std::string> listRequestHeader;
	listRequestHeader.push_back("Content-Type:application/json;charset=UTF-8");
	listRequestHeader.push_back(strToken);
	listRequestHeader.push_back("endPointType:ROLE_DEVELOP");

	CHttpLink httpLink;
	httpLink.CurlPostRequst(strUrl, json_data, _nPort, strRespose, listRequestHeader, true);

	// 截取Json数据
	CStringA strJsonData = InterceptJsonDataFromStr(strRespose);
	const char* result = new char[2 * strJsonData.GetLength() + 1];
	cJSON* cjson = cJSON_Parse(strJsonData, &result);
	delete[] result;
	if (cjson == NULL || cjson->type == cJSON_NULL)
		return;

	// 获取结果
	cJSON* pResultArr = cJSON_GetObjectItem(cjson, "result");
	if (NULL == pResultArr || pResultArr->type == cJSON_NULL)
		return;

	int nSize = cJSON_GetArraySize(pResultArr);
	cJSON* pSubItem = pResultArr->child;
	for (int i = 0; i < nSize; ++i)
	{
		cJSON* pSubChildItem = pSubItem->child;
		int nLength = cJSON_GetArraySize(pSubItem);
		MatDataValue dataValue;
		for (int j = 0; j < nLength; ++j)
		{
			CVariantData variantData = BuildVariantData(pSubChildItem);

			CString strKey = UTF8StdstringToCString(pSubChildItem->string);
			dataValue.keyValueMap[strKey] = variantData;
			pSubChildItem = pSubChildItem->next;
		}

		_matDataValueArr.push_back(dataValue);
		pSubItem = pSubItem->next;
	}

	cJSON_Delete(cjson);

2.3 Content-Type: multipart/form-data

void CDlgStandardResultApply::UploadFile(std::string& strUrl, std::string& strFilePath, std::string& strResult)
{
	std::string stdXmCode = CW2A(_strXmCode.GetString());
	std::string stdPrjCode = CW2A(_strPrjCode.GetString());	

	std::string strError;
	CString strResponseValue;

	CURL *curl;
	CURLcode res;
	curl = curl_easy_init();
	if (curl) {
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
		curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
		struct curl_slist *headers = NULL;
		headers = curl_slist_append(headers, "Content-Type: multipart/form-data");
		headers = curl_slist_append(headers, "endPointType: web");
		headers = curl_slist_append(headers, _strToken.c_str());
		headers = curl_slist_append(headers, "Cookie: JSESSIONID=82E632D537D25075EDD98E6BE1ADF0F7");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		curl_mime *mime;
		curl_mimepart *part;
		mime = curl_mime_init(curl);
		part = curl_mime_addpart(mime);
		curl_mime_name(part, "file");
		curl_mime_filedata(part, strFilePath.c_str());
		part = curl_mime_addpart(mime);
		curl_mime_name(part, "resultid");
		curl_mime_data(part, strResult.c_str(), CURL_ZERO_TERMINATED);
		part = curl_mime_addpart(mime);
		curl_mime_name(part, "projectCode");
		curl_mime_data(part, stdXmCode.c_str(), CURL_ZERO_TERMINATED);
		part = curl_mime_addpart(mime);
		curl_mime_name(part, "itemProjectCode");
		curl_mime_data(part, stdPrjCode.c_str(), CURL_ZERO_TERMINATED);
		curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

		std::string stdResponse; // post返回后的数据
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);          //绑定相应
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stdResponse);

		res = curl_easy_perform(curl);
		curl_mime_free(mime);
	
		strResponseValue = CA2W(stdResponse.c_str(), CP_UTF8);
	}
	curl_easy_cleanup(curl);

	if (res != CURLE_OK)
	{
		strError = curl_easy_strerror(res);
		return;
	}

	CString strKey = L"code";
	std::string stdKey = CW2A(strKey);
	std::string stdResValue = CW2A(strResponseValue);
	std::string stdResultCode;
	
	strError = GetJsonResultFromStr(stdResValue, stdResultCode, stdKey);
	if (!strError.empty())
	{
		CString strWError = strError.c_str();
		MessageBox(strWError, _T("提示"), MB_OK | MB_ICONINFORMATION);
		return;
	}

	CString strResuult = CA2W(stdResultCode.c_str(), CP_UTF8);
	if (L"0" != strResuult)
		return;
	
	CString strErrorInfo = L"上传成功!";
	MessageBox(strErrorInfo, _T("提示"), MB_OK | MB_ICONINFORMATION);
}

三、总结

  • 本文主要介绍C++如何使用libcurl发送post请求的3中content-type的封装
  • 如果觉得文章对你有用处,记得 点赞 收藏 转发 一波哦~

💬 往期优质文章分享

🚀 优质教程分享 🚀

  • 🎄如果感觉文章看完了不过瘾,可以来我的其他 专栏 看一下哦~
  • 🎄比如以下几个专栏:Python实战微信订餐小程序、Python量化交易实战、C++ QT实战类项目 和 算法学习专栏
  • 🎄可以学习更多的关于C++/Python的相关内容哦!直接点击下面颜色字体就可以跳转啦!
学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战 💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
?? C++ QT结合FFmpeg实战开发视频播放器??难度偏高分享学习QT成品的视频播放器源码,需要有扎实的C++知识!
💚 游戏爱好者九万人社区💚互助/吹水九万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Python零基础到入门 💙Python初学者针对没有经过系统学习的小伙伴,核心目的就是让我们能够快速学习Python的知识以达到入门

🚀 资料白嫖,温馨提示 🚀

关注下面卡片即刻获取更多编程知识,包括各种语言学习资料,上千套PPT模板和各种游戏源码素材等等资料。更多内容可自行查看哦!

请添加图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:00:47  更:2022-06-01 15:01:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 22:57:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码