【问题标题】:Why does indy return unreadable data but chrome loads it fine?为什么 indy 返回不可读的数据但 chrome 加载它很好?
【发布时间】:2018-12-10 01:59:31
【问题描述】:

我正在尝试对我的一个游戏服务器的 RESTAPI 发出 GET 请求。当我在 chrome 中加载它时,它会加载正确的 json 响应,但是当我尝试使用 indy 时,它只会给我一堆不可读的文本。

请求的 URL:http://129.232.180.125:28019/deaths.json

Chrome 响应:

印地回应:

Y;9[ÿÍZË7¼ç3öìDQ%ÿJÃÚØ,Öw   òï§IµzvXÓö{Ab¿ÿöÏÝ»÷Ä!¾»ûûîýBó»»÷ßOwïï><¼îþ}§ På¢&È÷ÇÇÓË
gP¤@¹(¬Dv&©ÙEµ¸®D"`»@ëJ¥E\¦£??Þ?Ù@%¤3¨µ òrÿaCHZÝÀÕ
¯[%ö1cÓÔB)QV¡÷àõ=¢oÅt¥þóR§Ó§§Ï®Ô¶â*ëEu<wKÜôiýUØ^VµcÓ@vêâ»ÈR©hPædÛ=û±ô~¡;±8¢¢ÒtÇ/§û
Si¿·Õ
Zô1-W¥²¾KdP¡tÇXýc--[ÛàÔ-Go¼aI4]ñôãÏǯÏ_& h¶@5Gá0Ú#!`u.éöæà¿i³ÇhFÜ]Q´µjÁ
d¼Ê%½|ÔRØ\­¡Ókbê;Â$`¹^ìX»Ó`ϢѤù»   i2S$Ýûöõ¯ÉÑ2    D(,öæÛý§ûÙ¯j\-AOÙ^&Gä£WK¥2\ÙW[%a»a\Ò' U½4ßß+¯>bV«ÏêUçq¡õÏIÜ
,1×çiJ¾¸¸^Ðh}_æéê{²Ú°pp¼²KÖ÷ÞNÄIß¼D÷W+K3ËûÔz:}ÚÞ5
SB^"ÕKªGè¸+¾ß^~$Õâ³6Tõ]2Õßr9¸%eàYYUrsJÏ`Êä³ë'£t8#®AB¨KϹëOAe9V ×Ís-£¬Ó鬺ùÜ\)µµ©±¢xÜj« ½ê(JRâÜ>\<M´@6Xd°ý~®i ÄCõBe;&©l³"¦}.uUè5(ÝE®V;BìðùôtúöðqÆÅ8~cÜ¡}{\h9Í©¡0²]Cèl¯s%qeÅô{Ø]zOöÞ|W-ÆöÎ%媫¦@çÎл[jѶÊÞÒÙq¤¸qZÛ/îÕ=KTÓ³ÿÒ=Go@Îì6*Z¯\W7¡ê!rM´'£¸ÇR­»[G%ëp"?+²q?!ÔU{n,QâsðÚ9÷Þòì³H¡#f<Î.ÛÂѲ­Ät$u\9KoËGpE9b+ NsQÏ>ÉIiÒQs8ôòVÖMó.Þ÷ex ½½îx!RNÇZH?×b@ Ó$v¥_SfçF«Q®n`|à`«T­®Ð¦©¸×5*<?qC´/ø©¿ÑJ¬ªï´´+ýÑHjiK( ;¤øÓA#mýH߬5v ¡µR
´RI{ÊPAn,&æF ,&Õ/ônÓÚ¨­oÄÀùYó}DUÿêà}C$e õ^LYæªYßÍX«Z2»ËeOæVqWvrW1ÚP«¿_kÆ-¢¢2Ar«ö©]x¢|4Ñ¿¯Y[¹">´¸(lÉÆÓÌå/BÙ!ìPGr£`¶Ê
[!ªóèsfÄt+­.v.5_jÎê'Ô8Õ
Ö1ÒøMÜÑõâ[®ÇÄ)ãZYàÜ;Q!Ëa2Û^Zìçsá¹Ø^´QZbKnk9&ÄKºý¼ý®Úú11pÀ¦Eç°¿9r¾«ÿ®yýÆà"ø×
 (ù ?Ko¼Þ!Τ¸ò¿^/ºo¼½åzãß*A9aãÔ°¥Ù8umÁàËuni(
    '-®®DÕêüý¸o¢z­äݲé/lßþËÁi-ö:IhÙ8£i?|Û×RÐØï/ÐÀ,I
°Ù¥xXIRê0¹\x9séU=ªajä ^Æ£À±b¼$ÞP6<fF!µ¡Àßù!ûí7t¨¬XRÀJï\VãØsþð»b¨´7B` FýÀJÕ´F 
6Ë

èög»&·ã«¶ÛýAuR®ÝåL¬.YÌÄÿ£0æÀ%dÅ)²dhs´k¯.Ûg%ÅÂ.sâ¬Úé
zµ½ ;¸Z}»ÕUH«;ébÿ£j£%³S÷ú~X´@ýgý:¹½ 0w@ºØHâ³·,`!«G(]íä,Q¡NØm¢Î°,ÔY`Ùi;Ò¦×b¤×?BûMd¡Çdª <ï"QÕýWÏ®µ±× "6'3ý¹¦wþGSCt7Ùäk Ne¾ªÑ¿Ò(múS Ô$DifA{ª*ö¥(-gg¶a³~v(dê©=Om+á½üí±6®yf°1²ÐNi(y`B»ò¦¹ÃàuS!kµ¡¡i÷6¦   hÖ½;r"¢R»yÆ&OªoE·VU´¹)_Q9Ç¥2lÑÀâîUhñ~¼4óß4"\µnøæèî½5Ç00fúiPàýLØ~¯é§?_HÙ&Í÷;Ynnw¯8àoü¬¼^+2

我的代码:

mmo1.Lines.Text := idhtp1.Get('http://129.232.180.125:28019/deaths.json');

【问题讨论】:

  • 我无权访问该代码。我正在使用这个文档:playrust.io/manual/#!api.md
  • 什么delphi版本?
  • Delphi 版本 10.2.3 我试过问他,但他说如果它在 chrome 中可以正常工作,那么我的代码应该可以工作。
  • 答案很简单,内容是gzip压缩的,所以必须解压...
  • 确认,我在标题中看到Content-Encoding: gzip。 Chrome 会自动检测并处理它,但在 Indy 中您必须手动执行此操作。

标签: rest delphi get firemonkey indy


【解决方案1】:

如果服务器头中有Content-Encoding: gzip,那么你必须解压数据。 这是一个完整且有效的示例(省略了对压缩内容的检查):

program SO51126032;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  IdHttp,
  IdZLib,
  Classes,
  System.SysUtils;

function GetServerData(Url : String) : String;
var
  Http : TIdHttp;
  Strm : TMemoryStream;
  OutStrm : TStringStream;
begin
  Http := TIdHttp.Create(nil);
  try
    Http.HandleRedirects := True;
    Http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
    Http.Request.AcceptEncoding := 'gzip';
    Strm := TMemoryStream.Create;
    try
      OutStrm := TStringStream.Create(TEncoding.UTF8);
      try
        Http.Get(URL, Strm);
        Strm.Position := 0;
        if TextIsSame(Http.Response.ContentEncoding, 'gzip') then
          DecompressStream(Strm, OutStrm)
        else
          OutStrm.CopyFrom(Strm, 0);
        end;
        Result := OutStrm.DataString;
      finally
        OutStrm.Free;
      end;
    finally
      Strm.Free;
    end;
  finally
    Http.Free;
  end;
end;

begin
  try
    Writeln(GetServerData('http://129.232.180.125:28019/deaths.json')); 
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

* 推荐方式 *

如果您将TIdCompressorZlib 分配给TIdHTTP,Indy 可以为您完成这项艰巨的工作,它会自动检测 gzip 压缩的内容并即时解压缩:

uses
  IdHttp,
  IdCompressorZLib,
  System.SysUtils;

function GetServerData(const URL : String) : String;
var
  Http : TIdHttp;
begin
  Http := TIdHttp.Create(nil);
  try
    Http.HandleRedirects := True;
    Http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
    Http.Compressor := TIdCompressorZLib.Create(Http);
    Result := Http.Get(URL);
  finally
    Http.Free;
  end;
end;

【讨论】:

  • 我没有投反对票。但是,如果您不使用TIdHTTP.Compressor,就像第一个示例中一样,请确保在调用DecompressStream() 之前检查TIdHTTP.Response.ContentEncoding'gzip' 属性。仅仅因为你告诉服务器你支持压缩(这个例子没有这样做,仅供参考)并不意味着服务器实际上会发送一个压缩响应。
  • @RemyLebeau:我刚刚回复了 OP 的代码,无论如何我编辑了答案以将未来的读者指向压缩器示例。
  • 我更新了您的示例,在手动解压缩之前查看了 ContentEncoding 属性。
猜你喜欢
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 2017-10-12
  • 2011-09-26
  • 2018-02-04
  • 1970-01-01
相关资源
最近更新 更多