簡體   English   中英

使用Indy 10.5.8.0和Delphi XE2的UTF-8 GET

[英]UTF-8 GET using Indy 10.5.8.0 and Delphi XE2

我正在用Delphi XE2編寫我的第一個Unicode應用程序,我偶然發現了對Unicode URL的GET請求的問題。

簡而言之,它是MP3標簽應用程序中的例程,它采用曲目標題和藝術家,並查詢Last.FM以查找相應的專輯,曲目編號和流派。

我有以下代碼:

function GetMP3Info(artist, track: string) : TMP3Data //<---(This is a record)
var
  TrackTitle,
  ArtistTitle : WideString;
  webquery    : WideString;

[....]

WebQuery := UTF8Encode('http://ws.audioscrobbler.com/2.0/?method=track.getcorrection&api_key=' + apikey + '&artist=' + artist + '&track=' + track);

//[processing the result in the web query, getting the correction for the artist and title]

// eg: for artist := Bucovina and track := Mestecanis, the corrected values are 
//ArtistTitle := Bucovina;
// TrackTitle := Mestecăniș;

//Now here is the tricky part:

webquery := UTF8Encode('http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=' + apikey + '&artist=' + unescape(ArtistTitle) + '&track=' + unescape(TrackTitle)); 
//the unescape function replaces spaces (' ') with '+' to comply with the last.fm requests

[some more processing]

end;

TMemo的webquery看起來恰到好處:

http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=e5565002840xxxxxxxxxxxxxx23b98ad&artist=Bucovina&track=Mestecăniş

然而,當我嘗試發送一個GET請求,使用webquery TIdHTTP (與ContentEncoding設置屬性'UTF-8' ),我在Wireshark的看到TIdHTTPGET “荷蘭國際集團使用ANSI請求URL數據:

/2.0/?method=track.getInfo&api_key=e5565002840xxxxxxxxxxxxxx23b98ad&artist=Bucovina&track=Mestec?ni?

以下是GET請求和響應的完整標頭:

GET /2.0/?method=track.getInfo&api_key=e5565002840xxxxxxxxxxxxxx23b98ad&artist=Bucovina&track=Mestec?ni? HTTP/1.1
Content-Encoding: UTF-8
Host: ws.audioscrobbler.com
Accept: text/html, */*
Accept-Encoding: identity
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.23) Gecko/20110920 Firefox/3.6.23 SearchToolbar/1.22011-10-16 20:20:07

HTTP/1.0 400 Bad Request
Date: Tue, 09 Oct 2012 20:46:31 GMT
Server: Apache/2.2.22 (Unix)
X-Web-Node: www204
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Max-Age: 86400
Cache-Control: max-age=10
Expires: Tue, 09 Oct 2012 20:46:42 GMT
Content-Length: 114
Connection: close
Content-Type: text/xml; charset=utf-8;

<?xml version="1.0" encoding="utf-8"?>
<lfm status="failed">
<error code="6">
    Track not found
</error>
</lfm>

困擾我的問題是,我是否在監督與設置TIdHTTP組件屬性相關的任何事情? 如何阻止我在應用程序中編寫的格式正確的URL以錯誤的格式發送到服務器?

要從track.getCorrection函數獲取XML響應,您可以使用以下內容:

uses
  IdHTTP, IdURI;

function GetMusicDataXML(const AArtist, ATrack: string): string;
var
  URL: string;
  IdHTTP: TIdHTTP;
const
  APIKey = '1a3d8080e427f4dxxxxxxxxxxxxxxxxx';
begin
  Result := '';
  IdHTTP := TIdHTTP.Create;
  try
    URL := TIdURI.URLEncode('http://ws.audioscrobbler.com/2.0/?method=track.getcorrection&api_key=' + APIKey + '&artist=' + AArtist + '&track=' + ATrack);
    Result := IdHTTP.Get(URL);
  finally
    IdHTTP.Free;
  end;
end;
 var ... webquery : WideString; ... WebQuery := UTF8Encode('http://ws.audioscrobbler.com/2.0/?method=track.getcorrection&api_key=' + apikey + '&artist=' + artist + '&track=' + track); 

這不符合你的想法。 在XE2中, UTF8Encode()返回一個UTF-8編碼的RawByteString ,然后將其分配給WideString RTL將UTF-8數據解碼回UTF-16字符串。 將該字符串傳遞給TIdHTTP.Get() ,它會在格式化實際HTTP請求時將其轉換為ASCII,從而丟失任何非ASCII字符。

正如@TLama所說,在將URL傳遞給TIdHTTP之前,您必須使用TIdURI對URL進行編碼。 TIdURI會將Unicode字符編碼為UTF-8(默認情況下 - 您可以根據需要指定編碼),然后將結果數據編碼為TIdHTTP不會丟失的ASCII兼容格式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM