WCF服务在使用gzip编码时返回不正确的Content-Length



我有一个包含过滤文本框和列表框的网页。对文本框的修改触发一个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"错误。


我用fiddler做了一些调查。

在所有响应(甚至是成功的响应)中,fiddler显示一个错误:

Fiddler在会话#n1中检测到协议违反。

内容长度不匹配:Response Header指示n2 bytes,但是服务器发送n3字节。

如果响应头指示的大小大于,则浏览器仍然可以解释结果。

如果响应头显示的大小小于实际大小,则浏览器无法解释结果。

这里要做的一个明显的假设是,响应处理代码读取Content-Length标头,并且不读取任何超过长度规定的数据。

我调查的下一步是比较1.6.1和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调用时,响应不压缩。


所以现在我可以做一个工作解决方案,这是覆盖默认的接受头,以确保它不包含"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压缩时,为什么内容长度头和实际内容长度之间存在差异?

我正在使用webHttpBinding的WCF服务

首先,非常好的问题。这个问题为我提供了足够的信息来解决我的问题。

我有一个类似的问题,并张贴修复在这里-这样它可能会帮助别人。

  1. Ajax get &post请求在IE中返回null

  2. 在其他浏览器中工作正常,但在fiddler中看到'Response Header指示n字节,但服务器发送了nn字节'消息。

这里要做的明显假设是响应处理代码读取Content-Length头,不再读取任何数据

我也这么认为!

在这种情况下,我很清楚一件事。请求/响应被篡改我试着切换回旧版本的jQuery(正如你的问题中提到的),但没有帮助。

修复——我打开了应用程序的web配置,通读了一遍。模块中有一个来自telerik的'RadCompression Module',删除它后一切都开始正常工作。

RadCompression模块是已知的错误,并导致压缩响应的多个问题。

如果你有类似的问题,试着检查什么可能会拦截你的请求/响应。

Response Header indicated 140 bytes, but server sent 254 bytes说得多。同样的情况是否与您使用的浏览器无关?如果是这样的话,我们可以说IE或jQuery 1.4.3以及IE中的后续版本在读取响应头中指定的字节数后不会读取字节,而其他浏览器则会读取所有内容。

也有可能(但我几乎不相信这一点),响应头是错误地形成仅为IE请求。然后,您必须查看IE和其他浏览器请求与您的服务代码之间的差异。也许你的服务专门处理IE请求?

计算JSON字符串中最后捕获的引号(")之后有多少字节将是有趣的。114也许?

相关内容

  • 没有找到相关文章

最新更新