Из командной строки у меня есть запрос curl с двумя параметрами запроса, которые используют фигурные скобки. Однако один работает только при кодировании URL-адреса, а другой работает только тогда, когда он не кодируется URL-адресом.
Вот пример запроса, который (как ни странно) работает из командной строки и возвращает данные для 3 идентификаторов. Я бы не ожидал, что это сработает, потому что 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"
Учитывая эти ограничения, когда первый вызов работает так, как я хочу, а второй и третий нет, как мне использовать libcurl в C++, чтобы первый вызов реплицировался? Я знаю, что 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 сделать странный запрос на скручивание, подобный первому? Потому что это единственный способ выполнить команду из командной строки с ожидаемым результатом получения данных только трех человек.
В качестве альтернативы, возможно, есть другой способ попробовать этот запрос на завивание, кроме 4 попыток выше? Должен ли я просто обратиться к владельцу API и спросить, почему ему нравится { закодировано в одних местах, а не в других?
Все примеры команд не имеют закрытия " и имеют недопустимые URL-адреса https:example.com. Это сделано намеренно?
@ 273K Нет, это было непреднамеренно, извините за это! Только что исправлено.
@DanielStenberg, когда я запускаю CURLOPT_VERBOSE, вывод говорит мне, что он преобразует каждую фигурную скобку в %7D/%7B. Из того, что я видел в Интернете, добавление -g помогло бы, но я не уверен, как это сделать с libcurl? Не могу найти документацию по добавлению -g
Команды по-прежнему не могут выполняться из-за незакрытого файла «. Как мы можем вам помочь, если мы не знаем, что вы делаете в execatly.
curl -X GET "https://httpbin.org/get?TIME=%7B%22TIME_TYPE%22%3A%22MESSAGE%22%2C%22MESSAGENUMBER%22%3A5%7D&P_ID=%7B1,2,3%7D" -H "accept: application/json" работает хорошо. Ошибка может быть на вашем сервере. Кстати, если {1,2,3} должен быть JSON, как TIME, это недопустимый JSON. Возможно, вы захотите [1,2,3]@ 273K Извините, я не могу предоставить точный API из соображений безопасности, я закрыл кавычки. TIME_TYPE предназначен для JSON, но P_ID обычно принимает один целочисленный идентификатор, за исключением того, что он работает для нескольких целочисленных идентификаторов, когда вы выполняете {x,y,z}. Мне нужна помощь, как заставить libcurl кодировать URL-адрес одного запроса (TIME_TYPE), но не кодировать URL-адрес другого (P_ID). Я также должен упомянуть, что он выдает ошибку с квадратными скобками [], поэтому единственная команда curl, которая работает, как и ожидалось, и возвращает данные 3 человек, является первой в моем вопросе. Я просто не могу понять, как точно передать это через libcurl
CURLOPT_URL ничего не кодирует. { и } не являются escape-символами, см. ibm.com/docs/en/planning-analytics/…. Проблема где-то, но не в завитке. Если вы не можете предоставить точные запросы, почему вы просите нас помочь? Спросите своих коллег.





Это ваши 4 строки запроса после декодирования URL.
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
Ни один из символов в строке вашего запроса не должен быть закодирован urlencode.
Учитывая, что у вас в основном есть два 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})");
CURLOPT_URL ничего не кодирует, я не понимаю, почему этот первый URL-адрес не будет работать как есть. Это не работает для инструмента командной строки, потому что он «забивается» на фигурные скобки, поэтому вам нужно отключить это с помощью -g, и тогда инструмент также должен принять этот URL-адрес L. АФАИКС.