如何执行GET编码JSON?

How to perform GET encoded JSON?

我想做的是使用 GET 方法执行带有参数和值的 CURL 请求,但使用 JSON.

我正在尝试执行以下操作:

curl -X GET \
-H "X-Parse-Application-Id: 12345_Example" \
-H "X-Parse-REST-API-Key: abcde_Example" \
-G \
--data-urlencode "where={ \"pin\":\"A string\" }" \
https://urlExample/classes/Pins

如您所见,约束键值的 where URL 参数应编码为 JSON。

这是我的代码:

std::size_t callback(
    const char* in,
    std::size_t size,
    std::size_t num,
    char* out)
{
    std::string data(in, (std::size_t) size * num);
    *((std::stringstream*) out) << data;
    return size * num;
}

    public: Json::Value query(const char* serverAddress, const char* applicationId, const char* restAPIKey) {
        CURL* curl = curl_easy_init();
    
        curl_slist* headerlist = NULL;
        headerlist = curl_slist_append(headerlist, applicationId);
        headerlist = curl_slist_append(headerlist, restAPIKey);
    
        // Set HEADER.
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    
        // Set remote URL.
        curl_easy_setopt(curl, CURLOPT_URL, serverAddress);
    
        // Don't bother trying IPv6, which would increase DNS resolution time.
        curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    
        // Don't wait forever, time out after 10 seconds.
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
    
        // Follow HTTP redirects if necessary.
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    
        // Response information.
        int httpCode(0);
        std::stringstream httpData;
    
        // Hook up data handling function.
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
    
        // Hook up data container (will be passed as the last parameter to the
        // callback handling function).  Can be any pointer type, since it will
        // internally be passed as a void pointer.
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &httpData);
    
        // Run our HTTP GET command, capture the HTTP response code, and clean up.
        curl_easy_perform(curl);
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
        curl_easy_cleanup(curl);
    
        if (httpCode == 200) {
            // Response looks good - done using Curl now. Try to parse the results.
            Json::Value jsonData;
            Json::CharReaderBuilder jsonReader;
            std::string errs;
    
            if (Json::parseFromStream(jsonReader, httpData, &jsonData, &errs)) {
                return jsonData["results"];
            }
            else {
                std::cout << "Could not parse HTTP data as JSON" << std::endl;
                std::cout << "HTTP data was:\n" << httpData.str() << std::endl;
                return NULL;
            }
        }
        else {
            std::cout << "Couldn't GET from " << serverAddress << " - exiting" << std::endl;
            return NULL;
        }
    }

我应该在我的代码中包含什么以便使用编码 JSON 执行 GET 方法?

根据我正在使用的服务器 API 的文档,在读取对象时,这就是它对 curl 的描述: back4app API Reference

READING OBJECTS:

To retrieve an object, you'll need to send a GET request to its class endpoint with your app's credentials in the headers and the query parameters in the URL parameters. This task can be easily accomplished just by calling the appropriated method of your preferred Parse SDK. Please check how to do it in the right panel of this documentation.

Request URL https://parseapi.back4app.com/classes/Pins

Method GET

Headers X-Parse-Application-Id: BCrUQVkk80pCdeImSXoKXL5ZCtyyEZwbN7mAb11f

X-Parse-REST-API-Key: swrFFIXJlFudtF3HkZPtfybDFRTmS7sPwvGUzQ9w

Parameters A where URL parameter constraining the value for keys. It should be encoded JSON.

Success Response Status 200 OK

Headers content-type: application/json;

Body a JSON object that contains a results field with a JSON array that lists the objects.

编辑:

基于:Daniel Stenberg's answer 我尝试了以下方法:

std::string temp = "where={ \"pin\":\"A string\" }";
char* encoded = curl_easy_escape(curl, temp.c_str(), temp.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, std::strlen(encoded));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, encoded);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");

但是没有成功。 libcurl 是否应该更新他们的 API 并在这种情况下包含这样的功能?

好的 - 我将再回答一次。这次正确。我掩盖了您在问题中发布文档的事实。完全跳过了它。不知道为什么我的大脑会那样做。也许它讨厌文档并本能地跳过它。

所以,你的问题的答案很简单。

保留问题中的原始代码(完全忽略您在编辑中发布的代码,这是完全错误的),但不要这样做:

curl_easy_setopt(curl, CURLOPT_URL, serverAddress);

这样做:

const std::string whereQuery(curl_easy_escape(curl, "{ \"pin\":\"A string\" }", 0));
const std::string url("https://parseapi.back4app.com/classes/Pins?where=" + whereQuery);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

抱歉拖延。我需要更好地阅读问题。