C/C++中libcurl的使用-提交 Http Post请求

2023-05-16

之前介绍了使用libcurl的HTTP GET将url地址中内容下载到本地 C/C++中libcurl的使用-Http GET方法使用详解,在更早的文章Linux下使用CURL模拟用户提交post表单中也介绍过在Linux环境使用curl命令提交POST表单。本文介绍使用libcurl的HTTP POST实现表单的提交,并获取表单的结果。

libcurl的相关接口已经在上一篇文章中介绍,本文只介绍新增的相关接口和参数选项。

CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,const char *);
//向curl_slist链表中追加参数,这些参数用于设置一个标准浏览器请求的相关参数。例如实际使用Chrome提交的请求参数如下:

这里写图片描述

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POST, long post);
//CURLOPT_POST:参数post置为1表示libcurl将执行普通的HTTP POST操作,同时也意味着应该使用"Content-Type: application/x-www-form-urlencoded"作为请求的头部。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POSTFIELDS, char *postdata); 
//CURLOPT_POSTFIELDS:指针postdata指向的是POST操作所提供的所有参数,postdata的数据格式应该和server端想要接收数据的格式相同,如JSON格式或者使用相关连词符组成的。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POSTFIELDSIZE, long size);
//CURLOPT_POSTFIELDSIZE:设置提交参数的大小,而不是依赖于libcurl默认使用strlen来衡量该大小。没有此项配置或者size被置为-1,都意味着由libcurl使用strlen来计算长度。如果提交的内容大小超过2GB,应该使用CURLOPT_POSTFIELDSIZE_LARGE参数替代CURLOPT_POSTFIELDSIZE。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_COOKIEFILE, char *filename);
//如果提交POST请求要读取cookie信息,可以使用如下的参数将cookie所在的地址传递进来,cookie数据的格式可以是旧版本的"Netscape / Mozilla"cookie格式,也可以是普通的HTTP header的dump文件。

示例代码:

#include <iostream>
#include <string>

#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

#include <stdlib.h>
#include <string.h>
using namespace std;

struct MemoryStruct 
{
    char *memory;
    size_t size;
    MemoryStruct()
    {
        memory = (char *)malloc(1);  
        size = 0;
    }
    ~MemoryStruct()
    {
        free(memory);
        memory = NULL;
        size = 0;
    }
};

size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)data;

    mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory) 
    {
        memcpy(&(mem->memory[mem->size]), ptr, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
    }
    return realsize;
}

int main()
{
    CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        cout<<"curl init failed"<<endl;
        return 1;
    }

    CURL *pCurl ;
    pCurl = curl_easy_init();

    if( NULL == pCurl)
    {
        cout<<"Init CURL failed..."<<endl;
        return -1;
    }

    string url = "http://{IP}:{PORT}/search";
    string filename = "result.json";

    curl_slist *pList = NULL;
    pList = curl_slist_append(pList,"Content-Type:application/x-www-form-urlencoded; charset=UTF-8"); 
    pList = curl_slist_append(pList,"Accept:application/json, text/javascript, */*; q=0.01"); 
    pList = curl_slist_append(pList,"Accept-Language:zh-CN,zh;q=0.8"); 
    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList); 

    curl_easy_setopt(pCurl, CURLOPT_URL, url.c_str() ); //提交表单的URL地址

    curl_easy_setopt(pCurl, CURLOPT_HEADER, 0L);  //启用时会将头文件的信息作为数据流输
    curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
    curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1L);

    //将返回结果通过回调函数写到自定义的对象中
    MemoryStruct oDataChunk;
    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &oDataChunk);
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 

    curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
    //post表单参数
    string strJsonData;
    strJsonData = "queryWord=CONTENT:码农&";
    strJsonData += "startTime=1507605327&" ;
    strJsonData += "endTime=1508210127&" ;
    strJsonData += "maxCount=500&" ;
    strJsonData += "contextLength=200" ;
    //libcur的相关POST配置项
    curl_easy_setopt(pCurl, CURLOPT_POST, 1L);
    curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, strJsonData.c_str());  
    curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE, strJsonData.size());


    res = curl_easy_perform(pCurl);

    long res_code=0;
    res=curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &res_code);

    if(( res == CURLE_OK ) && (res_code == 200 || res_code == 201))
    {
        FILE* fTmpMem = (FILE*)oDataChunk.memory;
        if (!fTmpMem) {

        }
        FILE *fp=fopen(filename.c_str(),"wb");
        if(!fp)
        {   
            cout<<"open file failed";
            return -1;
        }   

        fwrite(fTmpMem, 1, oDataChunk.size, fp);
        fclose(fp);
        return true;
    }

    curl_slist_free_all(pList); 
    curl_easy_cleanup(pCurl);
    curl_global_cleanup();

    return 0;
}

在上述代码中,使用libcurl的POST选项将表单数据提交到相应的服务器,在正确响应结果后,将返回的json格式的数据写到本地的磁盘文件上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++中libcurl的使用-提交 Http Post请求 的相关文章

  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke
  • 使用 file_get_content 发布数据

    我已经做了一些关于如何使用的研究file get content与帖子 我也读过this one https stackoverflow com questions 2445276 how to post data in php using
  • 是否可以将请求标头添加到 CORS 预检请求中?

    我有一个从外部服务器 不是服务器 访问 API 的网站 为网站提供服务 通过简单的XmlHttpRequest 见下文 那个API 需要将用于访问服务的 API 密钥添加为请求标头 然而 正如这些CORS https developer m
  • 在 HTTP 标头中发送 UTF-8 值会导致 Mojibake

    我想使用 servlet 发送阿拉伯语数据HTTPServletResponse给客户 我正在尝试这个 response setCharacterEncoding UTF 8 response setHeader Info arabicWo
  • 扩展(十进制,例如 400.1、401.4 等)HTTP 状态代码从何而来?

    我越来越多地看到十进制样式 HTTP 状态代码的激增 而且我似乎找不到任何 RFC 或其他 IETF 建议 甚至 W3C 草案或除 Microsoft IIS 文档之外的其他内容 请参阅https support microsoft com
  • Android httpclient文件上传数据损坏和超时问题

    我在 Android 中上传图像时遇到问题 我正在使用 apache httpmime 4 1 lib 代码是这样的 MultipartEntity reqEntity new MultipartEntity HttpMultipartMo
  • 如何在java中以编程方式访问网页

    有一个网页 我想从中检索某个字符串 为此 我需要登录 单击一些按钮 填充文本框 单击另一个按钮 然后就会出现字符串 我怎样才能编写一个java程序来自动执行此操作 是否有任何有用的库用于此目的 Thanks Try HtmlUnit htt
  • 如何使用 Java 以正确的编码检索 HTML 页面?

    如何使用页面编码中的 HTML 页面读取 HTTP 流 这是我用来获取 HTTP 流的代码片段 输入流读取器有编码可选参数 但我不知道如何获取它 URLConnection conn url openConnection InputStre
  • 转义用户数据,无需魔法引号

    我正在研究如何在来自外部世界的数据被用于应用程序控制 存储 逻辑等之前正确地对其进行转义 显然 随着 magic quote 指令在 php 5 3 0 中很快被弃用 并在 php6 中被删除 对于任何想要升级并进入新语言功能 同时维护遗留
  • 在express js中禁用http方法

    我正在我的 Express 应用程序上进行 nessus 测试 这是我得到的 基于每种方法的测试 HTTP 方法 ACL CHECKOUT COPY DELETE GET HEAD LOCK MERGE MKACTIVITY MKCOL 移
  • 使用 JSON 的 Pentaho HTTP Post

    我是 Pentaho 的新手 我正在尝试执行以下工作流程 从数据库中读取一堆行 做一些转换 将它们以 JSON 格式发布到 REST Web 服务 我已经使用输入步骤和 Json 输出步骤解决了前两个问题 但是 我在执行最后一步时遇到两个问
  • 是什么导致“线程被中止”异常随机发生并向浏览器显示 HTTP 标头和部分 HTML?

    发生的情况偶尔是随机的 而不是像您期望的那样将 HTML 返回到浏览器 它看起来有点像这样 线程正在中止 HTTP 1 1 200 OK 标题的其余部分 如 HTML 的 1 10 就是这样 他们实际上在浏览器窗口中收到了一堆文本 它不会一
  • Rails api 中阻止用户配置文件的最佳 HTTP 状态代码是什么?

    我在 Rails 中为社交应用程序编写了一个 API 这个应用程序就像Facebook一样 用户可以阻止其他用户 如果用户 A 阻止用户 B 则用户 B 无法查看用户 A 的个人资料页面 那么我应该返回的最佳 HTTP 代码状态是什么 40
  • Node.js:在检索 http 请求正文之前断开 http 请求连接

    我正在用 Node js 编写一个 http 服务器 我有一个客户端通过 HTTP POST 多部分 数据 将大文件上传到该服务器 我想接受唯一使用有效文件名上传文件的连接 我有一些条件 在服务器检索数据之前应断开无效文件名连接 我不知道如
  • 为什么http使用CRLF作为行分隔符?

    据我所知 使用LF因为行分隔符非常流行 但我想知道为什么许多文本协议 如 HTTP FTP 使用CRLF作为它的行分隔符 我不认为这些协议是为旧打字机发明的 那么这有什么历史原因吗 我尝试通过谷歌 stackoverflow 和维基百科搜索
  • 在ActivePython-2.6中安装pyCurl?

    我过去曾使用过 pyCurl 并让它与我的系统默认 python 安装一起使用 但是 我有一个项目需要 python 更具可移植性 并且我正在使用 ActivePython 2 6 到目前为止 我安装任何其他模块都没有问题 但安装 pyCu
  • 使用:text/plain; 有什么缺点吗?字符集=“UTF-8”

    我的网络服务器提供的内容在 95 的情况下只是简单的 ascii 但在极少数情况下 内容包含一些德语非 ASCII 字符 现在我可以设置content type通过检测内容是否包含任何非 ASCII 字符来响应标头 或者我可以始终设置响应标
  • 角度报告进度返回上传的文件总数,而不是进度

    在我的组件中我有这个 this authService addPost post subscribe data gt if data type HttpEventType UploadProgress console log data el
  • Android 套接字和 HTTP 响应标头

    有趣的是 我可能无意中找到了解决方案是否可以使用普通套接字连接发送 HTTP 请求并接收没有标头的响应 https stackoverflow com questions 8320574 我希望我忽略了一些东西 无论如何 我正在连接到 We
  • CURL 相当于使用 VBA 的 POST JSON 数据

    我知道这与之前提出的一些问题类似 但有些东西仍然对我不起作用 如何执行以下命令 curl X POST data statements json H Content Type application json user username p

随机推荐