使用gzip编码时,WCF服务返回不正确的内容长度 [英] WCF service returns incorrect Content-Length when using gzip encoding

查看:210
本文介绍了使用gzip编码时,WCF服务返回不正确的内容长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含过滤文本框和列表框的网页。修改文本框触发一个AJAX请求,返回值的数组,用于填充列表框。

我有问题,这些调用有时会失败,依赖于返回的数据的大小。小型返回的数据会导致错误,大尺寸的数据返回并成功地处理。

当我使用一个jQuery版本高于4.2才会出现这种问题。如果我使用jQuery 4.2版,我没有问题。


这里是调用code:

  jQuery.ajax(
            {
                缓存:假的,
                网址:../Services/CmsWebService.svc/GetAvailableVideosForCompany
                键入:GET,
                完成:功能(jqXHR,textStatus){
                    VAR的responseText = jqXHR.responseText;
                    jQuery的('#debugConsole)文本(responseText的)。
                    availableVideosPopulationState.isRunning = FALSE;
                    的setTimeout(populateAvailableVideosListBox,100);
                },
                数据:{companyIdString:queryParameters.companyIdField,
                    为TextFilter:queryParameters.filterText
                },
                数据类型:JSON,
                错误:函数(jqXHR,textStatus,errorThrown){
                    VAR为errorString ='错误的Ajax调用抛出:'+ textStatus +'错误:'+ errorThrown;
                    警报(为errorString);
                },
                成功:功能(数据,textStatus,jqXHR){
                    populateVideoListFromAjaxResults(数据);
                }
            }
             );
 

下面是调试控制台中的内容,如果两个元素返回:

  {D:[{__类型:一个ListEntry:#网站presentationLayer,文:SOJACKACT0310DSN1.mpg  - [SOJACKACT0310DSN1]","Value":"5565_5565"},{"__type":"ListEntry:#Website$p$psentationLayer","Text":"SOJACKACT0310DSN1Q.mpg -  [SOJACKACT0310DSN1Q],值:5566_5566}]}
 

但是,如果返回一个元素:

  {D:[{__类型:
 

所以,当然,我们得到一个未终止字符串常量错误。


我已经做了使用招一番调查。

在所有的响应(即使是成功的那些),提琴手显示错误:

  

提琴手检测违反协议会话# N1

     

内容长度不匹配:响应头指示的 N2 的字节,但   服务器发送的 N3 的字节数。

如果响应头指示尺寸的大于的比实际尺寸,那么结果可能仍然是由浏览器PTED间$ P $。

如果响应头指示不是的实际尺寸,那么浏览器不能跨preT的结果。

大小的

最明显的假设,使有,响应处理code读内容长度头,不看任何比这更多的数据规定的长度。

在我调查的下一步是比较的jQuery 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请求 - 由于:XMLHtt prequest
接受:应用/ JSON,文字/ javascript中,* / *; Q = 0.01
引用站点:HTTP://本地主机:52200 /网络/管理/ PlayerGroupEditor.aspx组ID = 76
接受语言:EN-AU
接受编码:gzip,紧缩
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
主持人:本地主机:52200
连接:保持活动
饼干: .ASPXAUTH=CE853BBD860F40F0026400610074006D006500640069006100310000002B5387799D71CC01002B5B5D62C771CC0100002F0000006B119589A7305098A560E57515498C56ECB332035F300427CDA2B28205D5E6B6
 

的jQuery 1.6.1响应报头

  HTTP / 1.1 200 OK
服务器:ASP.NET开发服务器/ 10.0.0.0
日期:星期一,2011 23时02分36秒格林尼治标准​​时间09月12日
的X ASPNET-版本:4.0.30319
内容编码:gzip
内容长度:140
缓存控制:私人
内容类型:应用程序/ JSON;字符集= UTF-8
连接:关闭
 

这里是请求头,当我使用jQuery 1.4.1。请注意,接受头是从jQuery 1.6.1的值不同。

  GET /Web/Services/CmsWebService.svc/GetAvailableVideosForCompany?_=1315870305531&companyIdString=2&textFilter=3DSBDL2 HTTP / 1.1
引用站点:HTTP://本地主机:52200 /网络/管理/ PlayerGroupEditor.aspx组ID = 76
内容类型:应用程序/ x-WWW的形式urlen codeD
的X请求 - 由于:XMLHtt prequest
接受:应用/ JSON,文字/ javascript中,* / *
接受语言:EN-AU
接受编码:gzip,紧缩
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
主持人:本地主机:52200
连接:保持活动
饼干: .ASPXAUTH=CE853BBD860F40F0026400610074006D006500640069006100310000002B5387799D71CC01002B5B5D62C771CC0100002F0000006B119589A7305098A560E57515498C56ECB332035F300427CDA2B28205D5E6B6
 

和响应返回给jQuery的4.1.1:

  HTTP / 1.1 200 OK
服务器:ASP.NET开发服务器/ 10.0.0.0
日期:星期一,2011 23点31分46秒格林尼治标准​​时间09月12日
的X ASPNET-版本:4.0.30319
内容长度:131
缓存控制:私人
内容类型:应用程序/ JSON;字符集= UTF-8
连接:关闭
 

那么明显的区别是:当呼叫通过jQuery 1.6.1做出的反应是COM pressed使用gzip,当呼叫通过jQuery 1.4.2作出的反应是不是COM pressed


所以,现在我可以做一个变通的解决方案,这是为了覆盖默认的接受的头,以确保它不包含Q = 0.01串。 (最好的解释我可以找到Q = 0.01是的此处,但我不明白为什么我的服务实现跨preting这是一个要求拉链拉上响应厉害。)

  //使AJAX调用,通过在公司ID和过滤字符串
        jQuery.ajax(
            {
                接受:应用/ JSON,文字/ javascript中,* / *,
                缓存:假的,
                网址:../Services/CmsWebService.svc/GetAvailableVideosForCompany
                键入:GET,
                完成:功能(jqXHR,textStatus){
                    VAR的responseText = jqXHR.responseText;
                    jQuery的('#debugConsole)文本(responseText的)。
                    availableVideosPopulationState.isRunning = FALSE;
                    的setTimeout(populateAvailableVideosListBox,100);
                },
                数据:{companyIdString:queryParameters.companyIdField,
                    为TextFilter:queryParameters.filterText
                },
                数据类型:JSON,
                错误:函数(jqXHR,textStatus,errorThrown){
                    VAR为errorString ='错误的Ajax调用抛出:'+ textStatus +'错误:'+ errorThrown;
                    警报(为errorString);
                },
                成功:功能(数据,textStatus,jqXHR){
                    populateVideoListFromAjaxResults(数据);
                }
            }
             );
 


所以,毕竟本次调查中,剩下的问题就是为什么有内容长度头和实际内容长度之间的差距时,反应是GZIP COM pressed?

我用用的WebHttpBinding WCF服务。

解决方案

首先,非常好的问题。这个问题向我提供了足够的信息来达到我的问题的解决方案。

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

  1. 阿贾克斯获取和放大器; POST请求是在IE浏览器返回null

  2. 对于请求提琴手
  3. 是工作的罚款中的浏览器中休息,但看到响应头表示n个字节,但是服务器发送ン字节的消息。

  

的明显的假设,使那里的是,响应处理   code读取Content-Length头不读取任何数据。

我也这么觉得!

在这种情况下,我是清楚的一件事。 东西被篡改的请求/响应。 我试图切换回的jQuery(如上文你的问题)的旧版本,但是这并没有帮助。

修复 - 我打开了我的应用程序的Web配置,并通过它读取。 有一个 从包含的Telerik模块RADCOM pression模块',并拆除其一切开始工作的罚款。

RADCOM pression模块被称为是越野车和COM $ P $导致多种问题pssing响应。

如果您有类似的问题,尝试检查可能被拦截您的请求/响应。

I have a web page containing a filtering text box and a list box. Modifications to the text box trigger an AJAX request, which returns an array of values with which to populate the list box.

I had problems with these calls failing sometimes, dependent on the size of the data returned. Small-sized returned data would result in an error, large-size data was returned and processed succesfully.

This problem only happens when I use a jQuery version greater than 4.2. If I use jQuery version 4.2, I don't have the problem.


Here is the code of the call:

        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);
                }
            }
             );

Here is the contents of the debug console if two elements are returned:

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

But if one element is returned:

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

So, of course, we get an "Unterminated String Constant" error.


I have done some investigation using fiddler.

On all responses (even the succesful ones), fiddler displayed an error:

Fiddler has detected a protocol violation in session #n1.

Content-Length mismatch: Response Header indicated n2 bytes, but server sent n3 bytes.

If the response header indicates a size greater than than actual size, then the results could still be interpreted by the browser.

If the response header indicates a size less than the actual size, then the browser could not interpret the results.

The obvious assumption to make there is that the response handling code reads the Content-Length header and doesn't read any more data than that stipulated in the length.

The next step in my investigation is to compare the request/response headers for jQuery version 1.6.1 (which breaks) and version 1.4.2 (which does not break).

jQuery 1.6.1 request header:

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 response headers

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

And here is the request header when I use jQuery 1.4.1. Notice that the Accept header is different from the jQuery 1.6.1 value.

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

And the response back to 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

So the obvious difference is that when the call is made via jQuery 1.6.1 the response is compressed using gzip, and when the call is made via jQuery 1.4.2 the response is not compressed.


So now I can do a work around solution, which is to override the default Accept header to ensure it does not contain the "q=0.01" string. (The best explanation I can find for "q=0.01" is here, but I fail to see why my service implementation is interpreting this as a request to zip up the response badly.)

        // 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);
                }
            }
             );


So after all this investigation, the remaining question is why is there a disparity between the content length header and the actual content length when the response is GZIP compressed?

I'm using a WCF service with webHttpBinding.

解决方案

First of all-Very good question. This question provided me with enough information to reach a solution for my problem.

I had a similar issue, and posting the fix here- so that it might help someone.

  1. Ajax get & post requests were returning null in IE

  2. Was working fine in rest of the browsers, but saw the 'Response Header indicated n bytes, but server sent nn bytes' message in fiddler for the request.

The obvious assumption to make there is that the response handling code reads the Content-Length header and doesn't read any more data

I think so too!

In this case, I was clear with one thing. Something was tampering the request/response. I tried switching back to older version of jQuery (as mentioned in your question), but that didn't help.

Fix- I opened up the web config of my application, and read through it. There was a 'RadCompression Module' from telerik included in modules, and on removal of it everything started working fine.

RadCompression module is known to be buggy and cause multiple issues by compressing the Response.

If you are having similar issues, try checking what might be intercepting your request/response.

这篇关于使用gzip编码时,WCF服务返回不正确的内容长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆