【问题标题】:Chrome failing to decompress gzip, content lengthChrome 无法解压 gzip,内容长度
【发布时间】:2011-07-08 16:42:55
【问题描述】:

我的 Silverlight 4 应用程序通过 WCF 服务从服务器下载了大量数据,因此我使用此处描述的技术实现了 gzip 压缩:http://forums.infragistics.com/blogs/anton_staykov/archive/2010/08/24/silverlight-wcf-service-compression-azure.aspx

简而言之,我扩展了 WCF gzip 编码器示例 (http://msdn.microsoft.com/en-us/library/ms751458.aspx) 以使用 Silverlight。服务器使用 gzip 压缩 WCF 响应,在客户端,浏览器 HTTP 堆栈在响应到达 Silverlight 之前自动解压缩响应。一切都很好,压缩在 IE 中效果很好。

然而,在 Chrome 中测试同样的东西会导致这个..

System.Xml.XmlException: The input source is not correctly formatted.
at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
at System.Xml.XmlBufferReader.ReadValue(XmlBinaryNodeType nodeType, ValueHandle value)
at System.Xml.XmlBinaryReader.ReadNode()
at System.Xml.XmlBinaryReader.Read()
at System.Xml.XmlBaseReader.ReadEndElement()
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.RealTimeDataServiceClientChannel.EndGetNowTime(IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataService.EndGetNowTime(IAsyncResult result)
at DataAccess.Model.Silverlight4.DataAccess.RealTimeDataService.RealTimeDataServiceClient.OnEndGetNowTime(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)

我在 Fiddler 中检查了来自两个浏览器的请求 + 响应,它们几乎完全相同,但有一个关键区别 - Chrome 的响应的内容长度设置不正确。我确定这就是 XML SOAP 无法解析的原因。由于内容长度不正确,Chrome 仅解压缩部分内容。是什么赋予了?为什么我的 WCF 服务会为 Chrome 而不是 IE 发回错误的内容长度?我只改变浏览器 - 代码相同,响应主体相同(提琴手可以很好地解压缩)。有人知道为什么会这样吗?

提琴手:

~~ Internet Explorer 9 ~~

请求

POST http://127.0.0.1:84/services/RealTimeDataService.svc/binary HTTP/1.1
Accept: */*
Referer: http://127.0.0.1:84/ClientBin/Silverlight4.View.xap
Accept-Language: en-US
Content-Length: 207
Content-Type: application/soap+msbin1
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 127.0.0.1:84
Connection: Keep-Alive
Pragma: no-cache

回应

HTTP/1.1 200 OK
Cache-Control: private,no-cache
Pragma: no-cache
Content-Length: 512
Content-Type: application/soap+msbin1
Content-Encoding: gzip
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 08 Jul 2011 16:18:09 GMT

~~ Chrome ~~

请求

POST http://127.0.0.1:84/services/RealTimeDataService.svc/binary HTTP/1.1
Host: 127.0.0.1:84
Connection: keep-alive
Referer: http://127.0.0.1:84/ClientBin/Silverlight4.View.xap
Content-Length: 207
Origin: http://127.0.0.1:84
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30
content-type: application/soap+msbin1
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

回应

HTTP/1.1 200 OK
Cache-Control: private,no-cache
Pragma: no-cache
Content-Length: 149
Content-Type: application/soap+msbin1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 08 Jul 2011 16:05:43 GMT
Content-Encoding: gzip

【问题讨论】:

  • 很奇怪。我不知道问题出在哪里,但是您可以通过创建一个应用程序来隔离它,该应用程序完全发送 IE 发送的内容,然后慢慢地一个一个地更改标题,使其看起来像 Chrome 发送的内容,直到您找出原因服务器发回不同的响应。
  • 是的,这是一个很奇怪的错误。感谢您的好主意,我将尝试隔离哪个请求标头影响响应。如果我想不通,我想我必须将解压逻辑放在 Silverlight 中。
  • 我发现我设置了一个错误的标题,现在内容长度是正确的。但是,它仍然无法在 Chrome 中运行。我正在使用 SharpZipLib 解决它并从我的 WCF 服务返回一个字节数组。我会在答案中发布。

标签: silverlight wcf http google-chrome gzip


【解决方案1】:

我最终实现了一种解决方法来压缩 WCF 服务响应并在 Silverlight 库上解压缩它。我使用了 SharpZipLib:

  1. 对于网络项目:http://sharpdevelop.net/OpenSource/SharpZipLib/
  2. 银光版:http://slsharpziplib.codeplex.com/

在我的 WCF 服务中,我有压缩和未压缩的方法。压缩的方法返回 byte[],它在 Silverlight 端被解码。我公开了返回原始对象的未压缩方法,因为我需要将这些对象的类公开给客户端。 (如果有人对如何做到这一点有更好的想法,我很想听听)

让您不要为这些响应设置内容编码 HTTP 标头,因为它们由 SL 客户端应用程序处理,而不是由浏览器处理。

我一直无法弄清楚为什么 Chrome 不会自动解压缩我的 WCF 响应,但是这种解决方法可以达到相同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 2011-12-06
    • 2015-02-06
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多