Chrome не может распаковать gzip, длина содержимого - PullRequest
3 голосов
/ 08 июля 2011

Мое приложение Silverlight 4 загружает довольно много данных с сервера через службу WCF, поэтому я реализовал сжатие gzip, используя описанную здесь методику: http://forums.infragistics.com/blogs/anton_staykov/archive/2010/08/24/silverlight-wcf-service-compression-azure.aspx

Короче говоря, я расширил кодировщик gzip WCF.образец (http://msdn.microsoft.com/en-us/library/ms751458.aspx) для работы с Silverlight.Сервер сжимает ответы WCF с помощью gzip, а на стороне клиента стек 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, и они почти идентичны, с одним существенным отличием - Content-Length для Response неправильно установлен для Chrome .Я уверен, что именно поэтому XML SOAP не удается разобрать. Chrome распаковывает только часть содержимого из-за неправильной длины содержимого.Что дает?Почему моя служба WCF отправляет неверную длину содержимого для Chrome, а не IE?Я ничего не меняю, кроме браузера - код идентичен, а тела ответа идентичны (Fiddler может распаковать оба прекрасно).Кто-нибудь знает, почему это происходит?

Скрипач:

~~ 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

~~ Хром ~~

Запрос

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

1 Ответ

0 голосов
/ 01 августа 2011

В итоге я применил обходной путь, чтобы сжать ответ службы WCF и распаковать его в библиотеке Silverlight. Я использовал SharpZipLib:

  1. Для веб-проекта: http://sharpdevelop.net/OpenSource/SharpZipLib/
  2. Версия Silverlight: http://slsharpziplib.codeplex.com/

В моей службе WCF у меня есть как сжатые, так и несжатые методы ... сжатые методы возвращают byte [], который декодируется на стороне Silverlight. Я раскрываю несжатые методы, которые возвращают необработанные объекты, потому что мне нужно, чтобы классы этих объектов были представлены на стороне клиента. (если у кого-то есть лучшее представление о том, как это сделать, я бы хотел это услышать)

Заставить вас не устанавливать заголовок HTTP кодировки контента для этих ответов, так как они обрабатываются клиентским приложением SL, а не браузером.

Я так и не смог понять, почему Chrome не распаковывает мой ответ WCF автоматически, но этот обходной путь достигает того же результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...