C++中使用cURL发送JSON请求

6

我有以下的cURL命令,在终端中能够正常工作。

curl --insecure -X POST --data "username=testuser&password=12345" https://m360-prototype.herokuapp.com/sessions.json

这个json api发送了一些参数,例如-- "status":{"code":200,"message":"OK"}

现在我想让我的c++程序执行它。我之前已经为ftp上传和下载设置和使用过cURL,但是我没有找到任何例子来实现这个。

我想知道如何将用户名和密码参数传递给json api,并从中获取响应。

这是我在网上找到的代码,但它没有起作用。

struct curl_slist *headers=NULL; // init to NULL is important

headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");

curl = curl_easy_init();
if(curl) {
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_URL, "https://m360-prototype.herokuapp.com/sessions.json");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=testuser&password=12345");

    curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    res = curl_easy_perform(curl);

    if(CURLE_OK == res) {
        char *ct;
        /* ask for the content-type */
        res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
        if((CURLE_OK == res) && ct)
            printf("We received Content-Type: %s\n", ct);
    }
}

如何从网络获得响应?我知道它将以字符串形式呈现,并且我足够能力来解析它。

我正在查找在终端上执行的curl命令传递的所有参数(--insecure,-X,POST,--data),以便对我要做的事情有一点了解。

我是一名图形程序员:)不太擅长Web服务。 我会非常感谢任何帮助。

3个回答

6
Curl命令有一个选项--libcurl。使用它可以帮助你找出正确的libcurl代码。
在你的工作Curl命令末尾添加这个选项和一个文件名,Curl将输出一个可用的libcurl c示例。

curl --insecure -X POST --data "username=testuser&password=12345" https://m360-prototype.herokuapp.com/sessions.json --libcurl test.cpp

用-lcurl选项编译输出的代码。

g++ -lcurl test.cpp -o testcurl

以下是我用于从c ++向node.js POST JSON的libcurl代码示例。
  CURLcode ret;
  CURL *hnd;
  struct curl_slist *slist1;
  std::string jsonstr = "{\"username\":\"bob\",\"password\":\"12345\"}";

  slist1 = NULL;
  slist1 = curl_slist_append(slist1, "Content-Type: application/json");

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_URL, "https://example.com/");
  curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, jsonstr.c_str());
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.38.0");
  curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1);
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;
  curl_slist_free_all(slist1);
  slist1 = NULL;

Node.js(Express)接收JSON的格式为:

{ username: 'bob', password: '12345' }


谢谢您!不过我有一个问题?我也在尝试使用node.js与RPC通信,但是我对curl或node.js知之甚少,对json稍微了解一点。您的代码是我需要的完美示例,但我还需要接收json响应并解析它。我花了几个小时查看curl库,但无法弄清楚如何接收和处理响应,最好是作为字符串或其他易于处理的格式。它只会返回响应代码。您有什么建议吗? - BriCo84
@BriCo84 我认为这个链接可能会有所帮助 https://gist.github.com/alghanmi/c5d7b761b2c9ab199157 - Rahim Khoja
1
好的,谢谢!现在它可以工作了。只需要解析一下 :) - BriCo84
我遇到了这个错误:“CURLOPT_TCP_KEEPALIVE在此范围内未声明”。 - user3798283

2

要发送POST数据,您需要告诉curl它在哪里。例如:

std::string data = "username=testuser&password=12345";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.length());
curl_easy_setopt(curl, CURLOPT_POST, 1);

要将响应读入内存中,稍微有些复杂 - 你需要有一个回调函数用于存储数据。这在curl文档中有一个例子(链接),尽管你可以将结果附加到std::string中,而不是像他们一样拥有自己的块结构。


我实际上添加了postfields,但我不知道我还必须发送它的长度。会尝试一下,然后发布结果。我已经使用curlFtpUpload处理了这样的回调函数。 :) - 2am
我在curl终端命令中使用了“--insecure”选项,但我在c++中似乎找不到对应的curl_easy_setopt选项。请问怎么做?我们的服务器是https的,而且目前没有证书,所以我需要这个选项。 - 2am

1
很大程度上取决于您发送请求的方式。
发送数据的方式很重要。如果您希望从服务器获得JSON格式的响应,则应以JSON格式发出请求。
除了The dark所说的内容之外,将其与JSON请求结合起来,我得到了我期望的结果。
以下代码对我有效...您发送到服务器的参数应该是JSON格式的---
std::string data = "{\"username\":\"testuser\",\"password\":\"12345\"}";
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);  // for --insecure option
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.length());
curl_easy_setopt(curl, CURLOPT_POST, 1);

你找到了 --insecure 选项吗?如果没有,我可以在我的另一台电脑上找找。 - The Dark
嗨,我找到了。在OSX中,我并不需要它,但当我把我的代码移植到Windows时,我需要使用--insecure选项。curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - 2am

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接