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请求 的相关文章

  • Angular2 http.post 被执行两次

    我遇到一个奇怪的问题 Angular2 的 RC1 Http 服务执行 http post 调用两次 我已经调试了我的应用程序 并且我知道这不是点击事件问题 导致核心服务调用的所有调用 public create json Object p
  • 从express.js 中删除所有标头

    我正在创建一个页面 其中有一些数据可以由另一个设备解析 我曾经使用 php 执行此操作 但现在将其移至 Node js 我需要从页面中删除所有标题 这样我就只有我的输出 此输出是对 GET 请求的响应 此刻我有 HTTP 1 1 200 O
  • 不允许使用 HTTP 谓词 POST 来访问路径“[我的路径]”

    我收到一条错误 指出 不允许使用 HTTP 动词 POST 来访问路径 我的路径 该错误是由于我正在实现一个使用 POST 方法的 HTML 表单元素并且未在其 ACTION 参数中显式定义 aspx 页面而引起的 例如
  • HttpGet 401 状态代码后跟 200 状态代码

    我使用 Apachage HttpComponent 访问 Web 服务时遇到奇怪的行为 我可以访问服务器日志 当我尝试连接到服务器并执行 httpGet 命令时 我可以在日志中首先看到 401 状态 http 未经授权 然后看到 200
  • 身份验证中的随机数使用

    在基于摘要的身份验证中 随机数由服务器生成 然而 在基于 OAuth 的身份验证中 随机数是由客户端生成的 我想知道是否有人知道差异的原因 随机数用于使请求唯一 在没有随机数的身份验证方案中 恶意客户端可以生成一次请求并重放多次 即使计算成
  • “双点”可以作为 URL 路径部分的一部分吗

    在 URL 中使用父目录双点是否有效且安全 如下例所示 http example com path to file jpg RFC3986 https www rfc editor org rfc rfc3986定义 URI 它描述了路径如
  • Rails - map.resources 的冗余 RESTFUL 操作? (新建、创建)

    我想知道为什么当您使用 map resources 在 Rails 中创建静态路线时 它会生成以下操作 新建 创建 编辑 更新 只声明一项行动有什么问题吗 create and update并做这样的事情 def create unless
  • 如何使用独立的 Jetty 进行服务器推送

    我正在尝试使用独立的 Jetty 在静态网站上测试服务器推送功能 我的网站由一个index html 1个CSS 一堆图像组成 目录结构为 Album index html style css images image 1 png a se
  • HTTP部分上传、断点续传的标准方法

    我正在开发 http 客户端 服务器框架 并寻找处理部分上传的正确方法 与使用带有 Range 标头的 GET 方法进行下载相同 但是 HTTP PUT 并不打算恢复 据我所知 PATCH 方法不接受 Range 标头 有没有办法通过 HT
  • asp.net/jQuery:使用 jQuery 将数据发布到弹出窗口 [IE]

    我正在尝试在 asp net 应用程序中使用 jQuery 将数据发布到弹出窗口 如果弹出窗口打开 我会收到三个错误 第一个错误是 Errror the value of the property is null or undefined
  • JS Sapper:将数据发布到服务器(正确的方法?)

    如何使用 Sapper JS lib 正确地将数据发布到服务器 说 我有一个页面 板编辑器 我可以在其中从用 SVG 编写的六边形网格中选择 取消选择图块 并在存储数组中添加 减去十六进制坐标 然后用户填写一个表单 其中包含板 名称 作者和
  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 在golang中获取TTFB(第一个字节的时间)值

    我正在尝试获取 TTFB 值和 Connect 值 c exec Command curl w Connect time connect TTFB time starttransfer Total time time total o dev
  • Play框架2.0 Form.bindFromRequest().get()返回空模型

    我需要从套接字通信接收相同的 POST 数据 这是发送 POST 并接收响应的代码 并且似乎工作正常 String data t URLEncoder encode Title UTF 8 u URLEncoder encode http
  • 当会话令牌无效时,我应该使用什么状态代码?

    创建 Web 服务 RESTful 时 当会话令牌无效时我应该使用什么状态代码 目前我公司的人给我发了一个404 未找到 但我认为这是不正确的 因为资源存在 也许我应该使用 401 Unauthorized 你怎么认为 您建议我在这种情况下
  • 有没有办法使用 ASP.NET 在用户离开页面时始终运行某些服务器端代码?

    我想知道当用户离开 ASP NET 中的页面时是否有任何方法可以始终运行一些服务器端代码 页面卸载事件不好 因为如果有人单击链接 则不会调用该事件 理想情况下 即使用户关闭浏览器 我也希望代码能够运行 我怀疑我所问的问题是不可能的 但问一下
  • Access-Control-Allow-Origin值跨站缓存

    我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点 只要客户端从不访问这两个站点 它似乎就可以工作 但如果它们这样做 就会出现缓存 跨站点问题 Allow cross origin location eot
  • 如何使用 Ruby on Rails 3 检查 HTTP 请求的“Content-Length”字段?

    我正在使用 Ruby on Rails 3 在我的视图文件中我有以下代码 为了避免服务器过载 我会在服务器接收上传文件之前检查上传文件的大小 这是因为 按下表单的提交按钮 服务器会先完整接收文件 然后再检查文件 我知道一个HTTP 请求有标
  • 为什么 websocket 需要使用 HTTP 进行打开握手?为什么不能成为一个独立的协议呢?

    Websocket 的设计方式是 通过使其握手成为有效的 HTTP 升级请求 其服务器可以与 HTTP 服务器共享端口 我对这个设计理念存有疑问 无论如何 WebSocket 协议都是一个独立的基于 TCP 的协议 为什么我们需要这个 HT
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http

随机推荐