c++ libcurl json rest

10
我正在尝试使用libcurl在C++中从REST网页下载JSON文件。如果我进入网页,以下代码可以工作,但如果我尝试访问JSON,则无法下载。
我认为这应该是一个简单的修复,但我找不到任何参考资料...
如果我进入网页,它会打开JSON,但此代码仅返回text/html; charset=utf-8。
??????????
CURL *curl;
CURLcode res;
    struct curl_slist *headers=NULL; // init to NULL is important 
    headers = curl_slist_append(headers, "Accept: application/json");   

curl = curl_easy_init();
if(curl) {

    curl_easy_setopt(curl, CURLOPT_URL, "http://web.com/api/json/123");
            curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    //curl_easy_setopt(curl, CURLOPT_URL, "http://web.com/123.html");//this works!!!
    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);
    }
}
/* always cleanup */ 
curl_easy_cleanup(curl);
3个回答

20
std::string ServerContent::DownloadJSON(std::string URL)
{   
    CURL *curl;
    CURLcode res;
    struct curl_slist *headers=NULL; // init to NULL is important 
    std::ostringstream oss;
    headers = curl_slist_append(headers, "Accept: application/json");  
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charset: utf-8"); 
    curl = curl_easy_init();

    if (curl) 
    {
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPGET,1); 
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,writer);
        res = curl_easy_perform(curl);

        if (CURLE_OK == res) 
        { 
            char *ct;         
            res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
            if((CURLE_OK == res) && ct)
                return *DownloadedResponse;
        }
    }

    curl_slist_free_all(headers);
}


static std::string *DownloadedResponse;

static int writer(char *data, size_t size, size_t nmemb, std::string *buffer_in)
{

    // Is there anything in the buffer?  
    if (buffer_in != NULL)  
    {
        // Append the data to the buffer    
        buffer_in->append(data, size * nmemb);

        // How much did we write?   
        DownloadedResponse = buffer_in;

        return size * nmemb;  
    }

    return 0;

}   

3
你有两个对 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 的调用,我认为第二个不必要。 - Ivaylo Strandjev
2
根据我的经验,似乎你应该将curl_slist_append的返回值分配回headers以修改列表。 - Ivaylo Strandjev
3
你漏掉了调用 curl_slist_free(headers),所以这段代码存在头部列表泄漏的问题。 - Pete Kirkham
1
@PeteKirkham 你漏了_all。curl_slist_free_all(headers); - lumingjing
你的 curl_slist_append 调用没有添加任何内容:你忽略了返回值。 - emlai
今天便利店似乎很冷清啊,哈哈。 - deadcow

1

我认为这与HTTP服务器上的配置有关。首先,您应该发送某种类型的指示,以表明您期望的类型,例如,添加像这样的 Accept 标头:

Accept: application/json

如果您没有指定您所期望的内容,服务器可能会在响应头Content-Type中返回默认的HTML,这就是curl向您报告的内容。


我尝试添加以下内容,但无法从服务器响应中获取实际数据... struct curl_slist *headers=NULL; // 初始化为NULL很重要 headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- Philip

0

我想读取JSON而不是放置它,是否有CURLOPT_READHEADER或其他方法可以读取从服务器返回的数据流? 顺便说一句,这对我在命令行上使用curl -i -H“Accept:application / json”-X GET web.com/api/json/123有效。 - Philip

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