delphi – TRestClient / TRestRequest错误地解码gzip响应
我试图读取一个REST API,它是gzip编码的.确切地说,我试图阅读StackExchange API.
我已经找到了问题Automatically Decode GZIP In TRESTResponse?,但由于某种原因,这个答案并没有解决我的问题. 测试设置 在XE5中,我添加了TRestClient,TRestRequest和具有以下相关属性的TRestResponse.我设置了客户端的BaseURL,请求的资源和参数,并将请求的AcceptEncoding设置为gzip,deflate,这应该使它自动解码gzipped响应. object RESTClient1: TRESTClient BaseURL = 'https://api.stackexchange.com/2.2' end object RESTRequest1: TRESTRequest AcceptEncoding = 'gzip,deflate' Client = RESTClient1 Params = < item Kind = pkURLSEGMENT name = 'id' Options = [poAutoCreated] Value = '511529' end item name = 'site' Value = 'stackoverflow' end> Resource = 'users/{id}' Response = RESTResponse1 end object RESTResponse1: TRESTResponse end 这导致url:
我调用这样的请求,有两个消息框来显示url和请求的结果: ShowMessage(RESTRequest1.GetFullRequestURL()); RESTRequest1.Execute; // Actual call ShowMessage(RESTResponse1.Content); 如果我在浏览器中调用该URL,我会得到一个正确的结果,这是一个json对象,其中包含我的一些用户信息. 问题 但是,在Delphi中,我没有得到JSON响应.实际上,我得到了一堆字节,这似乎是一个错误的gzip响应.我尝试使用TIdCompressorZlib.DecompressGZipStream()解压缩它,但它失败并出现ZLib错误(-3).当我自己检查响应的字节时,我看到它从#1F#3F#08开始.这特别奇怪,因为gzip标题应该是#1F#8B#08,所以#8B转换为#3F,这是一个问号. 所以在我看来,RESTClient试图将gzip流解码为好像是UTF-8响应,并且用问号替换了无效序列(#8B本身不是有效的UTF-8字符). 尝试(表面) 我做了很多实验,比如 >使用RESTResponse.RawBytes并尝试解码它.我注意到这个字节数组中的字节已经无效. TRESTResponse来源中的评论告诉我’RawBytes’已经被解码,所以这是有道理的. 不幸的是它仍然无效,我仍然得到了错误的回应. 尝试(深入VCL) 最后,我挖了一点,然后潜入TRestRequest.Execute.我不会在这里粘贴所有代码,但最终它会通过调用来执行请求 FClient.HTTPClient.Get(LURL,LResponseStream); FClient是链接到请求的TRESTClient,LResponseStream是TMemoryStream.我将LResponseStream.SaveToFile(‘…’)添加到手表中,因此它会保存这个未经处理的结果,等等,它给了我一个有效的gz文件,我可以解压缩以获取我的JSON. 解决方案中的错误? 但是,接下来几行,我看到这段代码: if FClient.HTTPClient.Response.CharSet > '' then begin LResponseStream.Position := 0; S := FClient.HTTPClient.ReadStringAsCharset(LResponseStream,FClient.HTTPClient.Response.CharSet); LResponseStream.Free; LResponseStream := TStringStream.Create(S); end; 根据此块上面的注释,这样做是因为内存流的内容“未根据可能存在的Encoding或Content-Type Charset参数进行编码”,这被VCL代码的编写者认为是Indy中的错误. 所以基本上,这里发生了什么:原始响应被视为一个字符串并转换为’正确’编码. FClient.HTTPClient.Response.CharSet是’UTF-8′,它确实是JSON的编码,但不幸的是,这种转换只能在解压缩流之后才能完成,但尚未完成.所以我认为这是一个错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |