HTTP POSTing

We get many questions regarding how to issue HTTP POSTs with libcurl the proper way. This chapter will thus include examples using both different versions of HTTP POST that libcurl supports.

The first version is the simple POST, the most common version, that most HTML pages using the <form> tag uses. We provide a pointer to the data and tell libcurl to post it all to the remote site:
第一个版本是最简单的Post,最通用的版本,大多数HTML网页所用的<form>方式。
我们提供一个指向数据的指针,然后告诉Libcurl把这个指针中的数据post到远端。

char *data="name=daniel&project=curl";
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/");

curl_easy_perform(easyhandle); /* post away! */

Simple enough, huh? Since you set the POST options with the CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the upcoming request.
当你使用 CURLOPT_POSTFIELDS 设置了post选项,接下来该句柄的所有请求都会使用这种post方式。

Ok, so what if you want to post binary data that also requires you to set the Content-Type: header of the post? Well, binary posts prevent libcurl from being able to do strlen() on the data to figure out the size, so therefore we must tell libcurl the size of the post data. Setting headers in libcurl requests are done in a generic way, by building a list of our own headers and then passing that list to libcurl.

如果想要post二进制数据,需要设置Content-Type,需要告诉Libcurl数据的长度,

struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type: text/xml");

/* post binary data */
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr);

/* set the size of the postfields data */
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L);

/* pass our list of custom made headers */
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);

curl_easy_perform(easyhandle); /* post away! */
curl_slist_free_all(headers); /* free the header list */

While the simple examples above cover the majority of all cases where HTTP POST operations are required, they don't do multi-part formposts. Multi-part formposts were introduced as a better way to post (possibly large) binary data and were first documented in the RFC 1867 (updated in RFC2388). They're called multi-part because they're built by a chain of parts, each part being a single unit of data. Each part has its own name and contents. You can in fact create and post a multi-part formpost with the regular libcurl POST support described above, but that would require that you build a formpost yourself and provide to libcurl. To make that easier, libcurl provides curl_formadd. Using this function, you add parts to the form. When you're done adding parts, you post the whole form.
curl_easy方式的Post已经满足了大多数场景的需求,但是multi-part可以更好的post。
叫做multi-part是因为他们又一个链表组成,每个part是一个单独的数据单元。
每个part有自己的名字和内容。
你可以自己建立一个formpost,然后提供给Libcurl调用。
但为了让这个过程更简单,libcurl提供了curl_formadd接口。
使用这个函数,你可以添加part到form中,
添加完成后,再把整个form发送出去。

The following example sets two simple text parts with plain textual contents, and then a file with binary contents and uploads the whole thing.

struct curl_httppost *post=NULL;
struct curl_httppost *last=NULL;
curl_formadd(&post, &last,
CURLFORM_COPYNAME, "name",
CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END);
curl_formadd(&post, &last,
CURLFORM_COPYNAME, "project",
CURLFORM_COPYCONTENTS, "curl", CURLFORM_END);
curl_formadd(&post, &last,
CURLFORM_COPYNAME, "logotype-image",
CURLFORM_FILECONTENT, "curl.png", CURLFORM_END);

/* Set the form info */
curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post);

curl_easy_perform(easyhandle); /* post away! */

/* free the post data again */
curl_formfree(post);

Multipart formposts are chains of parts using MIME-style separators and headers. It means that each one of these separate parts get a few headers set that describe the individual content-type, size etc. To enable your application to handicraft this formpost even more, libcurl allows you to supply your own set of custom headers to such an individual form part. You can of course supply headers to as many parts as you like, but this little example will show how you set headers to one specific part when you add that to the post handle:

Multipart formposts是由使用MIME类型分隔和头部的多个部分组成的链表,
这意味着链表的每个部分都有自己的头部来描述自己的数据类型、长度等
libcurl允许你设置自定义的头部
下面的例子演示如何指定头部信息:

struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type: text/xml");

curl_formadd(&post, &last,
CURLFORM_COPYNAME, "logotype-image",
CURLFORM_FILECONTENT, "curl.xml",
CURLFORM_CONTENTHEADER, headers,
CURLFORM_END);

curl_easy_perform(easyhandle); /* post away! */

curl_formfree(post); /* free post */
curl_slist_free_all(headers); /* free custom header list */

Since all options on an easyhandle are "sticky", they remain the same until changed even if you do call curl_easy_perform, you may need to tell curl to go back to a plain GET request if you intend to do one as your next request. You force an easyhandle to go back to GET by using the CURLOPT_HTTPGET option:
虽然所有easyhandle中的属性都是粘性的(指的是除非重新设置,否则不会变更)。
在以上的代码中,Http method已经被改为了post,如果想要重新使用get,可以使用如下代码重新设置:

curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);

Just setting CURLOPT_POSTFIELDS to "" or NULL will *not* stop libcurl from doing a POST. It will just make it POST without any data to send!
如果只是设置 CURLOPT_POSTFIELDS 为 ""或者 NULL,Libcurl仍然会继续使用post方式。
只不过Post的时候不带任何数据

[译]HTTP POSTing的更多相关文章

  1. 什么是PostBack(译)

    什么是PostBack(译) What is a postback? 下面的内容是针对ASP.NET新手的 PostBack什么时候被引发? PostBack由客户端浏览器引发.通常是用户操作(点击按 ...

  2. 支持行单击、双击事件的GridView和DataList控件(译)

    支持行单击.双击事件的GridView和DataList控件(译)         让GridView 和 DataList 控件响应鼠标单击.双击事件.并且,使用 ClientScript.Regi ...

  3. 【译】Android API 规范

    [译]Android API 规范 译者按: 修改R代码遇到Lint tool的报错,搜到了这篇文档,aosp仓库地址:Android API Guidelines. 58e9b5f Project ...

  4. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  5. Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新

    因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...

  6. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

  7. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  8. CSharpGL(31)[译]OpenGL渲染管道那些事

    CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...

  9. [译]基于GPU的体渲染高级技术之raycasting算法

    [译]基于GPU的体渲染高级技术之raycasting算法 PS:我决定翻译一下<Advanced Illumination Techniques for GPU-Based Volume Ra ...

随机推荐

  1. idea中javaweb的mysql8.0.15配置问题

    mysql8.0.x以后的版本在连接数据库的时候有些不同. 首先: Class.forName("com.mysql.cj.jdbc.Driver"); 其次: DriverMan ...

  2. js下载

    下载用ajax不好使,得用表单提交的方式 download:function(url,paramObj){ var doc = document; //使用一个隐藏的form表单执行提交,没有则创建 ...

  3. HTML5+CSS3设计界面

    近期在做一个关于房屋装修的手机上的项目,前台是用H5+C3完毕的,挂在微信上.全部相对来说不是非常难. 这段时间通过敲Html5+Css3.分享一些自己觉得值得学习的知识. 都非常easy.自己操作一 ...

  4. ubuntu14.04 的ibus不能卸载(安装fcitx输入法框架时可能有这个需求)。出现无system setting有用程序

    每年的ubuntu新版本号公布,都会吸引一大批热血青年. 关注越多也让ubuntu越来越好了. 使用ubuntu的人都会在安装系统之后马上安装顺手的输入法,也可能不会.看人. 安装输入法,对于中文输入 ...

  5. ZOJ3662:Math Magic(全然背包)

    Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common m ...

  6. 关于mysql建立索引 复合索引 索引类型

    这两天有个非常强烈的感觉就是自己在一些特别的情况下还是hold不住,脑子easy放空或者说一下子不知道怎么去分析问题了,比方,问"hash和btree索引的差别",这非常难吗.仅仅 ...

  7. 【bzoj4443】[Scoi2015]小凸玩矩阵

    第K大也就是第n-K+1小,所以就可以的二分答案了 (江哥讲过一道类似题) 二分答案找出比当前答案小的数的位置的坐标,判断一下是否可以选出满足不在同一行同一列的n-K+1个数,然后就可以跑匈牙利了,对 ...

  8. Linux服务器 /var/spool/clientmqueue 目录下产生大量文件的删除办法

    检查linux发现server中的磁盘分区空间超过98%,登录到服务器查看 [root@localhost etc]# df -hFilesystem 容量 已用 可用 已用% 挂载点/dev/hda ...

  9. TableLayout与MigLayout

    最近新接触的两个Layout,另外之前用的GridBagLayoutHelper以及最近听说的Qt for java的QCSS据说也不错, 只是Qt的跨平台需要单独发布,假如使用QT for java ...

  10. POJ 1477:Box of Bricks

    Box of Bricks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19949   Accepted: 8029 De ...