Формирую строку GET-запроса для отправки через TIdHTTP. Запрос с параметрами, и при этом значение одного параметра может содержать всякие "нехорошие" символы, как то "&", "#", "=" и т.п. (пробелов, вроде, быть не может; и слава богу). Как я понимаю, такую строку нужно конвертировать, заменив плохие символы на последовательность % и код символа. Но есть ли готовая функция (в Delphi вообще или в Indy)? Пока всё, что нашёл, это TIdURI.URLEncode, но этот зверь тупо кодирует всю строку. но как он поймёт, что в строке http://myhost.com?paramname=qwert&asdf=zxcv
всего один параметр — paramname с значением qwert&asdf=zxcv
а не два? Я подумал, что надо бы значение стрёмного параметра закодировать, а потом уже добавлять его в строку запроса. Так ли это? Или существует какой-то более правильный способ?
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
Не-а... не пугает. Просто я немного представляю себе, что такое AI, и как это работает. Вся теория была разработана ещё в 60-70-х годах прошлого века. А сейчас AI выстрелил, потому что появилось много дешёвых компьютерных ресурсов, доступных любому.
Да я тоже представляю.Я неправильно выразился, наверное. Не пугает, а поражает скорость и качество развития технологии. Где-то год назад я давал задачку попроще и ответ был очень так себе. Сейчас похоже на правду.
Я сейчас часто бываю в Китае, у меня много переписки и документов на китайском. Переводы доверил ChatGPT, у меня подписка.Стандартный тест, когда переводишь туда и обратно AI проходит более, чем удовлетворительно, особенно если есть уже контекст. Зачастую обратный перевод лучше, чем исходный текст.
>>> Но, Geo, согласитесь, это немного пугает? :)
Не-а... не пугает. Просто я немного представляю себе, что такое AI, и как это работает. Вся теория была разработана ещё в 60-70-х годах прошлого века. А сейчас AI выстрелил, потому что появилось много дешёвых компьютерных ресурсов, доступных любому.
Кстати, если бы зашёл сюда Сергей Перовский (а он больше в теме), то он много бы мог порассказать, на что способен искусственный интеллект. Например, про доказательство теорем :)
Кстати, я бы, наверное, реализовал бы код не так, как предложил AI. Если бы делал по уму, то, скорее всего, сделал бы класс, куда добавлял пары параметр - значене (примерно как в TStrings, только не строку, а пару строк), дал бы возможность с ними поработать (удалить, изменить значение), а потом получить готовую строку запроса.
Ради прикола скормил ваш запрос ChatGPT-4o. Вот ответ:
Вы совершенно правы в том, что значение параметров в URL необходимо кодировать, чтобы избежать неправильного интерпретирования специальных символов, таких как &, #, = и т.д. Для этого действительно нужно закодировать только значение параметра, а не всю строку целиком.
Функция TIdURI.URLEncode, как вы заметили, кодирует всю строку, что не совсем подходит для вашей задачи, когда нужно кодировать только значения параметров. Правильный подход заключается в том, чтобы закодировать значение параметра отдельно, а затем составить строку запроса.
К сожалению, в стандартной библиотеке Delphi и даже в Indy нет готовой функции, которая бы автоматически определяла параметры и кодировала только их значения. Однако, вы можете использовать TIdURI.URLEncode для кодирования значений параметров перед добавлением их в строку запроса.
Пример правильного формирования строки GET-запроса:
uses
IdURI, SysUtils;
function EncodeParamValue(const Value: string): string;
begin
Result := TIdURI.URLEncode(Value);
end;
function BuildGETRequest(const BaseURL: string; const Params: array of string): string;
var
i: Integer;
EncodedParams: string;
begin
EncodedParams := '';
for i := 0 to High(Params) div 2 do
begin
if i > 0 then
EncodedParams := EncodedParams + '&';
EncodedParams := EncodedParams + Params[i * 2] + '=' + EncodeParamValue(Params[i * 2 + 1]);
end;
В этом примере BuildGETRequest принимает базовый URL и массив параметров. Каждый параметр состоит из имени и значения. Значение кодируется с помощью EncodeParamValue (которая просто вызывает TIdURI.URLEncode), а затем формируется конечная строка запроса.
Таким образом, вы вручную кодируете значения параметров, что позволяет вам контролировать, какие части строки запроса кодируются, а какие остаются неизменными.
Если что, я выкрутился. Написал свою функцию кодирования значения параметра вот так:
const
Digits: array[0..15] of AnsiChar = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
function UrlEncodeParam(const AParamValue: String): String;
var
Buf: AnsiString;
ParamValue: Utf8String;
C: AnsiChar;
P: PAnsiChar;
i: Integer;
begin
ParamValue := Utf8Encode(AParamValue);
SetLength(Buf, Length(ParamValue) * 3);
P := @Buf[1];
for i := 1 to Length(ParamValue) do
begin
C := AnsiChar(ParamValue[i]);
case C of
' ':
P^ := '+';
'0'..'9','A'..'Z','a'..'z','_':
P^ := C;
else
P^ := '%';
Inc(P);
P^ := Digits[Ord(C) div 16];
Inc(P);
P^ := Digits[Ord(C) mod 16];
end;
Inc(P);
end;
Result := Copy(Buf, 1, P - PAnsiChar(@Buf[1]));
end;
А закодированные таки образом значения вставляю в строку запроса через Format
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.