C/C libcurl如何POST表单提交,只是普通的web表单提交数据

Posted

技术标签:

【中文标题】C/C libcurl如何POST表单提交,只是普通的web表单提交数据【英文标题】:C / C libcurl how to POST form submission, just ordinary web form submission data 【发布时间】:2020-06-23 01:04:16 【问题描述】:

我想模拟web表单提交到php API,但是失败了,我尝试了很多方法。 我的代码

#define HADES "Content-Type:application/x-www-form-urlencoded;charset=utf-8"

int SendPacket(char *packet, const char *server)

    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    if (!curl) 
        return -1;
    
    CURLcode ret;
    struct curl_slist *haderlist = NULL;
    struct curl_httppost *post = NULL;
    struct curl_httppost *last = NULL;
    haderlist = curl_slist_append(haderlist, HADES);

    curl_formadd(&post, &last, CURLFORM_COPYNAME, "username",
             CURLFORM_COPYCONTENTS,
             "11111111111", CURLFORM_END);
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "password",
             CURLFORM_COPYCONTENTS,
             "111111", CURLFORM_END);
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "client", CURLFORM_FILE,
             "wap", CURLFORM_END);


    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, haderlist);
    curl_easy_setopt(curl, CURLOPT_URL, server);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

    //SendData
    ret = curl_easy_perform(curl);
    if (ret != CURLE_OK ) 
        curl_easy_strerror(ret);

        return -1;
    
    return 0;

我把post的参数改成这个格式就可以正常发送了:username = 11111 & password = 1111 & client = wap 不用form_add函数,但是不知道怎么做. 如何纠正这个问题?我不知道

【问题讨论】:

【参考方案1】:

您正在混合表单编码。 CURLOPT_POSTFIELDS 需要 URL 编码形式(例如 username = 11111&password =1111&client=wap),而 curl_formadd 生成 multipart/form-data 编码形式。将CURLOPT_HTTPPOST 与curl_formadd 一起使用,或者在url 编码的表单上使用CURLOPT_POSTFIELDS

在任何一种情况下,您都不需要添加 Content-Type 标头,因为它会自动添加。

【讨论】:

但我觉得主要不是这个造成的。我试图删除 curl_slist_append (haderlist, HADES) 函数,仍然无法正常解析【参考方案2】:
 tried to use mime to successfully solve the code as follows

int SendPacket(char *packet, const char *server)

    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    if (!curl) 
        return -1;
    
    CURLcode ret;

    curl_mime *mime;
    curl_mimepart *part1;
    curl_mimepart *part2;
    curl_mimepart *part3;

    mime = curl_mime_init(curl);
    part1 = curl_mime_addpart(mime);
    part2 = curl_mime_addpart(mime);
    part3 = curl_mime_addpart(mime);

    //Add part to the mime handle, each of which is a pair of key(name)value(data)
    curl_mime_data(part1, "111111", CURL_ZERO_TERMINATED);
    curl_mime_name(part1,"username");
    curl_mime_data(part2, "111111", CURL_ZERO_TERMINATED);
    curl_mime_name(part2, "password");
    curl_mime_data(part3, "wap", CURL_ZERO_TERMINATED);
    curl_mime_name(part3, "client");

    curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
    curl_easy_setopt(curl, CURLOPT_URL, server);    
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);

    ret = curl_easy_perform(curl);
    if (ret != CURLE_OK ) 
        curl_easy_strerror(ret);

        return -1;
    
    return 0;


Above is mock to simulate web form submission

【讨论】:

以上是关于C/C libcurl如何POST表单提交,只是普通的web表单提交数据的主要内容,如果未能解决你的问题,请参考以下文章

C/C++使用libcurl库发送http请求(get和post可以用于请求html信息,也可以请求xml和json等串)

C++用libcurl通过HTTP以表单的方式Post数据到服务器

libcurl get和post的区别

php中如何防止刷新一次提交一次

asp.net如何把表单提交到别的页面而不是本页面,用POST方式

如何使用 libcurl 进行 HTTP 发布?