带有 Unicode 参数的 C++ Builder TRestRequest
C++ Builder TRestRequest with Unicode parameter
我正在使用 TRestRequest 从服务器获取数据。我需要用 Unicode 字符串值填充参数:"ôpen"。但是,我使用此 Unicode 字符串作为查询参数调用 Execute 时遇到崩溃。
我的代码:
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?
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
HTTP header 在 GET
请求中没有意义,仅在 POST
请求中。
Embarcadero 的 REST 框架无法正确处理 non-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();
否则,切换到 Indy 的 TIdHTTP
组件:
UnicodeString Response = IdHTTP1->Get(L"http://server/XXX/collection1" + Form1->teReuqestHandler->Text + L"?q=" + TIdURI::ParamsEncode(Form1->teQuery->Text, IndyTextEncoding_UTF8));
我正在使用 TRestRequest 从服务器获取数据。我需要用 Unicode 字符串值填充参数:"ôpen"。但是,我使用此 Unicode 字符串作为查询参数调用 Execute 时遇到崩溃。
我的代码:
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?
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
HTTP header 在 GET
请求中没有意义,仅在 POST
请求中。
Embarcadero 的 REST 框架无法正确处理 non-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();
否则,切换到 Indy 的 TIdHTTP
组件:
UnicodeString Response = IdHTTP1->Get(L"http://server/XXX/collection1" + Form1->teReuqestHandler->Text + L"?q=" + TIdURI::ParamsEncode(Form1->teQuery->Text, IndyTextEncoding_UTF8));