【问题标题】:JSON request using cURL in C++在 C++ 中使用 cURL 的 JSON 请求
【发布时间】:2014-05-27 23:43:18
【问题描述】:

我在 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++ 程序执行它。我之前已经设置并使用了 cURL 来从 ftp 示例进行 ftp 上传和下载。但是我没有找到任何例子来做到这一点。

我想知道如何将用户名和密码参数传递给 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),以便对我必须做的事情一无所知。

我是一名图形程序员 :) 不太擅长网络服务。 如有任何帮助,我将不胜感激。

【问题讨论】:

    标签: c++ json curl


    【解决方案1】:

    Curl 命令有一个选项 --libcurl 。它应该可以帮助您找出要使用的正确 libcurl 代码。

    将此选项与文件名一起添加到您的工作 Curl 命令的末尾,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

    下面是我用来将 JSON 从 c++ POST 到 node.js 的 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:

    { 用户名:'bob',密码:'12345' }

    【讨论】:

    • 谢谢你!我有一个问题吗?我也在尝试与 node.js 上的 RPC 进行通信,但我对 curl 或 node.js 知之甚少,对 json 只知之甚少。您的代码是我需要的完美示例,但是我还需要接收 json 响应并对其进行解析。我花了几个小时查看 curl 库,但我不知道如何接收和处理响应,最好是字符串或简单的东西。它只是发回响应代码。你有什么建议吗?
    • @BriCo84 我认为这个链接可能会有所帮助gist.github.com/alghanmi/c5d7b761b2c9ab199157
    • 成功了,谢谢!它现在工作。只需要解析它:)
    【解决方案2】:

    要发送帖子数据,您需要告诉 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);
    

    要将响应读入内存,它有点复杂 - 您需要调用一个回调函数来存储数据。有一个 in the curl docs 的示例,尽管您可以将结果附加到 std::string 中,而不是像他们那样拥有自己的块结构。

    【讨论】:

    • 我实际上添加了 postfields,但我不知道我还必须发送它的长度。会尝试一下,并发布结果。我已经用 curlFtpUpload 处理了这样的回调函数。 :)
    • 我在 curl 终端命令中提到了“--insecure”选项,我似乎在 c++ 中找不到 curl_easy_setopt 选项。它是如何完成的?我需要这个,因为我们的服务器是 https,我们现在没有任何证书
    【解决方案3】:

    很大程度上取决于您发送请求的方式。

    发送数据的方式很重要。如果您希望服务器以 json 格式响应,您也应该以 json 格式请求。

    连同上面黑暗所说的,将它与 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 选项了吗?如果没有,我可以在我的另一台计算机上查找。
    • 嗨,我确实找到了。我在 OSX 中不需要它,但是当我在 Windows 中移植我的代码时,我需要使用 --insecure 选项。 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    猜你喜欢
    • 2018-03-13
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2015-12-05
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    相关资源
    最近更新 更多