在命令行中,我有一个带有两个使用大括号的查询参数的curl请求。然而,一个只在url编码时起作用,另一个只在不是时起作用url编码。
下面是一个请求示例,它(奇怪地)从命令行工作并返回3个id的数据。我不希望它工作,因为TIME
是url编码与花括号(%7B
和%7D
),但P_ID
不是:
curl -X GET "https://example.com/search?TIME=%7B%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5%7D&P_ID={1,2,3}"
更奇怪的是,以下调用不起作用,似乎忽略了P_ID
字段,并为每个人提供数据:
-
curl -X GET "https://example.com/search?TIME=%7B%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5%7D&P_ID=%7B1,2,3%7D"
-
curl -X GET "https://example.com/search?TIME=%7B%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5%7D&P_ID=1&P_ID=2&P_ID=3"
-
curl -X GET "https://example.com/search?TIME={%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5}&P_ID=1&P_ID=2&P_ID=3"
在这些约束条件下,第一个调用按我希望的那样工作,但第二个和第三个调用没有,那么我如何在c++中使用libcurl来使第一个调用被复制?我知道CURLOPT_URL
编码所有内容,因此它将在TIME
和P_ID
中编码大括号。我试过像下面这样使用CURLUPART
,但无济于事。
void *curlHandle;
curl_easy_reset(curlHandle);
CURLU *url = curl_url();
curl_url_set(url, CURLUPART_URL, "example.com", 0);
curl_url_set(url, CURLUPART_QUERY, "P_ID={1,2,3}", CURLU_APPENDQUERY);
curl_url_set(url, CURLUPART_QUERY, "TIME=%7B%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5%7D", CURLU_APPENDQUERY);
curl_url_set(url, CURLUPART_SCHEME, "https", 0);
curl_url_set(url, CURLUPART_PATH, "/search/", 0);
curl_easy_setopt(curlHandle, CURLOPT_CURLU, url);
curl_easy_perform(curlHandle);
我得到这样的响应:
*没有URL集
Curl失败,错误3:URL使用错误/非法格式或缺少URL。0重试剩余
总结:我如何让libcurl发出像上面第一个那样奇怪的curl请求?因为这是我可以从命令行执行的唯一方法,并且只获得3个人的数据的预期结果。
或者,除了上面的4次尝试之外,是否还有其他方法来尝试这个curl请求?我应该只是接触到API所有者,并问为什么它喜欢{
编码在一些地方,而不是其他地方?
这些是url解码后的4个查询字符串。
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3}
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3}
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID=1&P_ID=2&P_ID=3
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID=1&P_ID=2&P_ID=3
查询字符串中的任何字符都不需要进行unlencoded。
假设你有两个url。
这些都是url,以及在服务器上解码的查询字符串url:
https://example.com?TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID=1&P_ID=2&P_ID=3
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID=1&P_ID=2&P_ID=3
https://example.com?TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3}
TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3}
我不认为您的查询字符串导致错误。
看来你搞错了:
CURLU *url = curl_url();
也许应该是:
CURLU *url= curl_url();
curl_url_set(url, CURLUPART_URL,
R"(https://example.com?TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3})", 0);
或者直接将URL传递给简单句柄:
curl_easy_setopt(curlHandle, CURLOPT_URL, R"(https://example.com?TIME={"TIME_TYPE":"MESSAGE","MESSAGENUMBER":5}&P_ID={1,2,3})");