如何实现TRestClient Delphi XE5对UTF-8编码字符串的支持?

更新于
2026-10-03 10:52:10
2阅读来源:SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计530个文字,预计阅读时间需要3分钟。

我想在Delphi XE5中使用新的TRest组件来开发推送文。我正在寻找一种方法来处理UTF8编码包含ISO-8859-1字符的推送文。下面的代码有效,但涉及到代码页转换等。这是否是一个更好的方法?任何人吗? procedure TTwitterAp;

我想在Delphi XE5中使用新的TRest组件发送推文.我正在寻找一种方法来UTF8编码包含IS0-8859-1字符的推文.下面的代码有效,但涉及代码页转换等.这是更好的方法吗?任何人?

procedure TTwitterApi.Send(Tweet: string); begin Reset; // Encode as UTF8 within (UTF-16 Delphi) string Tweet := EncodeAsUTF8(Tweet); FRestRequest.Resource := '1.1/statuses/update.json'; FRestRequest.Method := rmPOST; FRestRequest.Params.AddItem('status', Tweet, pkGETorPOST); FRestRequest.Execute; end; function TTwitterApi.EncodeAsUTF8(UnicodeStr: string): string; var UTF8Str: AnsiString; TempStr: RawByteString; begin TempStr := UTF8Encode(UnicodeStr); SetLength(UTF8Str, Length(TempStr)); Move(TempStr[1], UTF8Str[1], Length(UTF8Str)); Result := UTF8Str; end; Twitter的1.1 / statuses / update.json URL要求数据以application / x-www-form-urlencoded格式编码,因此您需要将TRESTClient.ContentType属性设置为ctAPPLICATION_X_WWW_FORM_URLENCODED(默认设置为ctNone).

对于UTF-8,TRESTClient在内部使用Indy,而Indy支持使用用户指定的字符集对出站数据进行编码,但Embarcadero似乎没有将该功能添加到其TRESTClient接口(但它确实处理了响应中的字符集).我不知道为什么Embarcadero会省略这样一个重要的特征.将字符串数据编码为UTF-8(你做得不正确,BTW)是不够的,但你还必须告诉Twitter数据是UTF-8编码的(通过内容的charset属性 – 输入REST标头),就我所见,TRESTClient不允许你这样做.我不知道TRESTClient是否使用指定的默认字符集发送REST请求,但查看其源代码,我认为没有,但我没有尝试过.

至少,您需要修复EncodeAsUTF8()函数.它不会产生一个包含UTF-8编码八位字节的UnicodeString,就像你认为的那样.它生成一个UTF-8编码的AnsiString,然后使用RTL的默认Ansi代码页将其转换为UTF-16编码的UniodeString,因此您正在调用丢失UTF-8数据的数据转换.试试这个:

function TTwitterApi.EncodeAsUTF8(UnicodeStr: string): string; var UTF8Str: UTF8String; I: Integer; begin UTF8Str := UTF8String(UnicodeStr); SetLength(Result, Length(UTF8Str)); for I := 1 to Length(UTF8Str) do Result[I] := Char(Ord(UTF8Str[I])); end;

这应该允许TRESTClient至少在其POST数据中对正确的UTF-8数据进行url编码.但是您仍然必须处理Content-Type请求标头中缺少的charset属性的问题(除非在未指定charset时Twitter默认为UTF-8).

现在,所有这些说,如果你发现解决TRESTClient问题并不适合你,那么我建议改用Indy的TIdHTTP组件(它有一个更准确的应用程序/ x-www-form-urlencoded实现比TRESTClient正在使用),例如:

procedure TTwitterApi.Send(Tweet: string); var Params: TStringList; begin Reset; Params := TStringList.Create; try FParams.Add('status=' + Tweet); FIdHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; FIdHTTP.Request.Charset := 'utf-8'; FIdHTTP.Post('api.twitter.com/1.1/statuses/update.json', Params, IndyTextEncoding_UTF8); finally Params.Free; end; end;

标签:U

本文共计530个文字,预计阅读时间需要3分钟。

我想在Delphi XE5中使用新的TRest组件来开发推送文。我正在寻找一种方法来处理UTF8编码包含ISO-8859-1字符的推送文。下面的代码有效,但涉及到代码页转换等。这是否是一个更好的方法?任何人吗? procedure TTwitterAp;

我想在Delphi XE5中使用新的TRest组件发送推文.我正在寻找一种方法来UTF8编码包含IS0-8859-1字符的推文.下面的代码有效,但涉及代码页转换等.这是更好的方法吗?任何人?

procedure TTwitterApi.Send(Tweet: string); begin Reset; // Encode as UTF8 within (UTF-16 Delphi) string Tweet := EncodeAsUTF8(Tweet); FRestRequest.Resource := '1.1/statuses/update.json'; FRestRequest.Method := rmPOST; FRestRequest.Params.AddItem('status', Tweet, pkGETorPOST); FRestRequest.Execute; end; function TTwitterApi.EncodeAsUTF8(UnicodeStr: string): string; var UTF8Str: AnsiString; TempStr: RawByteString; begin TempStr := UTF8Encode(UnicodeStr); SetLength(UTF8Str, Length(TempStr)); Move(TempStr[1], UTF8Str[1], Length(UTF8Str)); Result := UTF8Str; end; Twitter的1.1 / statuses / update.json URL要求数据以application / x-www-form-urlencoded格式编码,因此您需要将TRESTClient.ContentType属性设置为ctAPPLICATION_X_WWW_FORM_URLENCODED(默认设置为ctNone).

对于UTF-8,TRESTClient在内部使用Indy,而Indy支持使用用户指定的字符集对出站数据进行编码,但Embarcadero似乎没有将该功能添加到其TRESTClient接口(但它确实处理了响应中的字符集).我不知道为什么Embarcadero会省略这样一个重要的特征.将字符串数据编码为UTF-8(你做得不正确,BTW)是不够的,但你还必须告诉Twitter数据是UTF-8编码的(通过内容的charset属性 – 输入REST标头),就我所见,TRESTClient不允许你这样做.我不知道TRESTClient是否使用指定的默认字符集发送REST请求,但查看其源代码,我认为没有,但我没有尝试过.

至少,您需要修复EncodeAsUTF8()函数.它不会产生一个包含UTF-8编码八位字节的UnicodeString,就像你认为的那样.它生成一个UTF-8编码的AnsiString,然后使用RTL的默认Ansi代码页将其转换为UTF-16编码的UniodeString,因此您正在调用丢失UTF-8数据的数据转换.试试这个:

function TTwitterApi.EncodeAsUTF8(UnicodeStr: string): string; var UTF8Str: UTF8String; I: Integer; begin UTF8Str := UTF8String(UnicodeStr); SetLength(Result, Length(UTF8Str)); for I := 1 to Length(UTF8Str) do Result[I] := Char(Ord(UTF8Str[I])); end;

这应该允许TRESTClient至少在其POST数据中对正确的UTF-8数据进行url编码.但是您仍然必须处理Content-Type请求标头中缺少的charset属性的问题(除非在未指定charset时Twitter默认为UTF-8).

现在,所有这些说,如果你发现解决TRESTClient问题并不适合你,那么我建议改用Indy的TIdHTTP组件(它有一个更准确的应用程序/ x-www-form-urlencoded实现比TRESTClient正在使用),例如:

procedure TTwitterApi.Send(Tweet: string); var Params: TStringList; begin Reset; Params := TStringList.Create; try FParams.Add('status=' + Tweet); FIdHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; FIdHTTP.Request.Charset := 'utf-8'; FIdHTTP.Post('api.twitter.com/1.1/statuses/update.json', Params, IndyTextEncoding_UTF8); finally Params.Free; end; end;

标签:U