C++ Builder TRestRequest с параметром Юникод
Я использую TRestRequest для получения данных с сервера. Мне нужно заполнить параметр строковым значением Unicode: "ôpen". Тем не менее, я получаю сбой, вызывающий Выполнить с этой строкой Юникода в качестве параметра запроса.
Мой код:
RESTRequest->ResetToDefaults();
RESTRequest->AddParameter("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8 ", TRESTRequestParameterKind::pkHTTPHEADER);
// Get Indexing Status
RESTRequest->Resource = "XXX/collection1"+ Form1->teReuqestHandler->Text+"?";
RESTRequest->Method = rmGET;
// replace all space in name field with '\ '
UnicodeString lcQuery = Form1->teQuery->Text; // this value should be support french language or ...
// Body
RESTRequest->AddParameter("q",lcQuery, TRESTRequestParameterKind::pkGETorPOST);
// Run
String str1 = RESTRequest->GetFullRequestURL();
RESTRequest->Execute(); // here when pass "ôpen" to lcQuery, it crash
Как правильно добавить "ôpen" в мой URL?
1 ответ
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Заголовок HTTP не имеет значения в GET
запрос, только в POST
запрос.
Платформа Embarcadero REST неправильно обрабатывает кодировки не ASCII. Несмотря на то, что он использует Indy внутри, он не использует обработку кодировок Indy. Таким образом, для отправки данных в кодировке UTF-8 вам необходимо:
кодировать
UnicodeString
UTF-8 вручную, а затем поместите октеты UTF-8 обратно вUnicodeString
такTRESTRequest
можете отправить их:UnicodeString EncodeAsUtf8(const UnicodeString &s) { UTF8String utf8 = s; UnicodeString ret; ret.SetLength(utf8.Length()); for (int x = 1; x <= utf8.Length(); ++x) ret[x] = (WideChar) utf8[x]; return ret; } ... RESTRequest->ResetToDefaults(); RESTRequest->Method = rmGET; RESTRequest->Resource = L"XXX/collection1" + Form1->teReuqestHandler->Text; RESTRequest->AddParameter(L"q", EncodeAsUtf8(Form1->teQuery->Text), TRESTRequestParameterKind::pkGETorPOST); String str1 = RESTRequest->GetFullRequestURL(); RESTRequest->Execute();
закодируйте данные параметра самостоятельно:
#include <IdGlobal.hpp> #include <IdURI.hpp> RESTRequest->ResetToDefaults(); RESTRequest->Method = rmGET; RESTRequest->Resource = L"XXX/collection1" + Form1->teReuqestHandler->Text; RESTRequest->AddParameter(L"q", TIdURI::ParamsEncode(Form1->teQuery->Text, IndyTextEncoding_UTF8), TRESTRequestParameterKind::pkGETorPOST, TRESTRequestParameterOptions() << TRESTRequestParameterOption::poDoNotEncode); String str1 = RESTRequest->GetFullRequestURL(); RESTRequest->Execute();
Или же:
#include <IdGlobal.hpp> #include <IdURI.hpp> RESTRequest->ResetToDefaults(); RESTRequest->Method = rmGET; RESTRequest->Resource = L"XXX/collection1" + Form1->teReuqestHandler->Text + L"?q={q}"; RESTRequest->AddParameter(L"q", TIdURI::ParamsEncode(Form1->teQuery->Text, IndyTextEncoding_UTF8), TRESTRequestParameterKind::pkURLSEGMENT, TRESTRequestParameterOptions() << TRESTRequestParameterOption::poDoNotEncode); String str1 = RESTRequest->GetFullRequestURL(); RESTRequest->Execute();
В противном случае переключитесь на Инди TIdHTTP
составная часть:
UnicodeString Response = IdHTTP1->Get(L"http://server/XXX/collection1" + Form1->teReuqestHandler->Text + L"?q=" + TIdURI::ParamsEncode(Form1->teQuery->Text, IndyTextEncoding_UTF8));