Служба WCF возвращает неверную длину содержимого при использовании кодировки gzip - PullRequest
7 голосов
/ 12 сентября 2011

У меня есть веб-страница с текстовым полем фильтрации и списком.Изменения в текстовом поле инициируют запрос AJAX, который возвращает массив значений, которыми можно заполнить список.

У меня иногда возникали проблемы, когда эти вызовы не выполнялись, в зависимости от размера возвращаемых данных.Возвращенные данные небольшого размера могут привести к ошибке, данные большого размера будут возвращены и успешно обработаны.

Эта проблема возникает только тогда, когда я использую версию jQuery более 4.2.Если я использую jQuery версии 4.2, у меня нет проблем.Вот код вызова:

        jQuery.ajax(
            {
                cache: false,
                url: "../Services/CmsWebService.svc/GetAvailableVideosForCompany",
                type: "GET",
                complete: function (jqXHR, textStatus) {
                    var responseText = jqXHR.responseText;
                    jQuery('#debugConsole').text(responseText);
                    availableVideosPopulationState.isRunning = false;
                    setTimeout(populateAvailableVideosListBox, 100);
                },
                data: { "companyIdString": queryParameters.companyIdField,
                    "textFilter": queryParameters.filterText
                },
                dataType: 'json',
                error: function (jqXHR, textStatus, errorThrown) {
                    var errorString = 'Error thrown from ajax call: ' + textStatus + 'Error: ' + errorThrown;
                    alert(errorString);
                },
                success: function (data, textStatus, jqXHR) {
                    populateVideoListFromAjaxResults(data);
                }
            }
             );

Вот содержимое консоли отладки, если возвращаются два элемента:

{"d":[{"__type":"ListEntry:#WebsitePresentationLayer","Text":"SOJACKACT0310DSN1.mpg - [SOJACKACT0310DSN1]","Value":"5565_5565"},{"__type":"ListEntry:#WebsitePresentationLayer","Text":"SOJACKACT0310DSN1Q.mpg - [SOJACKACT0310DSN1Q]","Value":"5566_5566"}]}

Но если возвращается один элемент:

{"d":[{"__type":"

Итак, конечно, мы получаем ошибку «Unterminated String Constant».

Я провел некоторое расследование с использованием скрипача.

Во всех ответах (даже успешных) фиддлер отображал ошибку:

Фиддлер обнаружил нарушение протокола в сеансе # n1 .

Несоответствие длины содержимого: указан заголовок ответа n2 байт, но сервер отправил n3 байт.

Если заголовок ответа указывает размер больше, чем , чем фактический размер, результаты все равно могут интерпретироваться браузером.

Если заголовок ответа указывает на размер меньше фактического размера, то браузер можетне интерпретировать результаты.

Очевидное предположение, которое можно сделать, заключается в том, что код обработки ответа читает заголовок Content-Length и не считывает больше данных, чем указано в длине.

Следующим шагом в моем исследовании является сравнение заголовков запроса / ответа для версии 1.6.1 jQuery (которая ломается) и версии 1.4.2 (которая не ломается).

Заголовок запроса jQuery 1.6.1:

GET /Web/Services/CmsWebService.svc/GetAvailableVideosForCompany?companyIdString=2&textFilter=3DSBDL2&_=1315869366142 HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://localhost:52200/Web/Admin/PlayerGroupEditor.aspx?groupid=76
Accept-Language: en-au
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: localhost:52200
Connection: Keep-Alive
Cookie: .ASPXAUTH=CE853BBD860F40F0026400610074006D006500640069006100310000002B5387799D71CC01002B5B5D62C771CC0100002F0000006B119589A7305098A560E57515498C56ECB332035F300427CDA2B28205D5E6B6

jQuery 1.6.1 заголовки ответа

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 12 Sep 2011 23:02:36 GMT
X-AspNet-Version: 4.0.30319
Content-Encoding: gzip
Content-Length: 140
Cache-Control: private
Content-Type: application/json; charset=utf-8
Connection: Close

А вот заголовок запроса, когда я использую jQuery 1.4.1.Обратите внимание, что заголовок Accept отличается от значения jQuery 1.6.1.

GET /Web/Services/CmsWebService.svc/GetAvailableVideosForCompany?_=1315870305531&companyIdString=2&textFilter=3DSBDL2 HTTP/1.1
Referer: http://localhost:52200/Web/Admin/PlayerGroupEditor.aspx?groupid=76
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*
Accept-Language: en-au
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: localhost:52200
Connection: Keep-Alive
Cookie: .ASPXAUTH=CE853BBD860F40F0026400610074006D006500640069006100310000002B5387799D71CC01002B5B5D62C771CC0100002F0000006B119589A7305098A560E57515498C56ECB332035F300427CDA2B28205D5E6B6

И ответ обратно на jQuery 4.1.1:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 12 Sep 2011 23:31:46 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 131
Cache-Control: private
Content-Type: application/json; charset=utf-8
Connection: Close

Итак, очевидная разницачто при вызове через jQuery 1.6.1 ответ сжимается с помощью gzip, а при вызове через jQuery 1.4.2 ответ не сжимается.

Так что теперь я могу обойти решение, которое состоит в переопределении заголовка Accept по умолчанию, чтобы убедиться, что он не содержит строку "q=0.01".(Лучшее объяснение, которое я могу найти для "q=0.01", это здесь , но я не понимаю, почему моя реализация службы интерпретирует это как запрос на сжатие ответа.)

        // Make the AJAX call, passing in the company id and the filter string
        jQuery.ajax(
            {
                accepts: 'application/json, text/javascript, */*',
                cache: false,
                url: "../Services/CmsWebService.svc/GetAvailableVideosForCompany",
                type: "GET",
                complete: function (jqXHR, textStatus) {
                    var responseText = jqXHR.responseText;
                    jQuery('#debugConsole').text(responseText);
                    availableVideosPopulationState.isRunning = false;
                    setTimeout(populateAvailableVideosListBox, 100);
                },
                data: { "companyIdString": queryParameters.companyIdField,
                    "textFilter": queryParameters.filterText
                },
                dataType: 'json',
                error: function (jqXHR, textStatus, errorThrown) {
                    var errorString = 'Error thrown from ajax call: ' + textStatus + 'Error: ' + errorThrown;
                    alert(errorString);
                },
                success: function (data, textStatus, jqXHR) {
                    populateVideoListFromAjaxResults(data);
                }
            }
             );

Таким образом, после всего этого исследования остается вопрос: почему существует несоответствие между заголовком длины содержимого и фактической длиной содержимого, когда ответ сжат GZIP?

Я использую службу WCF с webHttpBinding.

Ответы [ 2 ]

5 голосов
/ 17 февраля 2012

Прежде всего - очень хороший вопрос.Этот вопрос предоставил мне достаточно информации, чтобы найти решение для моей проблемы.

У меня была похожая проблема, и я опубликовал исправление здесь, чтобы оно могло кому-то помочь.

  1. Ajax-запросы get & post возвращали ноль в IE

  2. Работал нормально в остальных браузерах, но увидел, что «заголовок ответа указал n байтов, но сервер отправил nn байтов»в fiddler для запроса.

Очевидное предположение, которое необходимо сделать, состоит в том, что код обработки ответа читает заголовок Content-Length и больше не читает данные

Я тоже так думаю!

В этом случае мне было ясно одно. Что-то вмешивалось в запрос / ответ. Я попытался вернуться к более старой версии jQuery (как упоминалось в вашем вопросе), но это не помогло.

Fix- Я открыл веб-конфигурацию своего приложения и прочитал ее.В Telerik был включен 'RadCompression Module' от telerik, и после его удаления все стало работать нормально.

Известно, что модуль RadCompression глючит и вызывает множественные проблемы при сжатии ответа..

Если у вас возникли похожие проблемы, попробуйте проверить, что может перехватывать ваш запрос / ответ.

1 голос
/ 12 сентября 2011

Response Header indicated 140 bytes, but server sent 254 bytes говорит о многом.Происходит ли то же самое независимо от используемого вами браузера?Если это так, мы можем сказать, что IE или jQuery 1.4.3 и далее в IE не читают байты после чтения такого количества байтов, как указано в заголовке ответа, в то время как другие браузеры все равно читают весь контент.

Это такжеВозможно (пока я вряд ли верю в это), что заголовок ответа неправильно сформирован только для запросов IE.Затем вы должны посмотреть на различия между IE и другими запросами браузера и вашим сервисным кодом.Может быть, ваши службы специально обрабатывают запросы IE?

Было бы интересно подсчитать, сколько байтов осталось после последней захваченной кавычки (") в вашей строке JSON.114 может быть?

...