问题
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.
回答1:
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.
Ajax get & post requests were returning null in IE
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.
回答2:
Response Header indicated 140 bytes, but server sent 254 bytes
says much. Does the same happen independently of the browser you use? If so, we may say that IE or jQuery 1.4.3 and further in IE does not read bytes after reading as many bytes as specified in Response Header, while other browsers read all the content anyway.
It is also possible (yet I hardly believe this) that response header is wrongly formed only for IE requests. Then you must look at the differences between IE and other browser requests and your service code. Maybe your services handles IE requests specifically?
It would be interesting to calculate how much bytes there is after the last captured quotation mark ("
) in your JSON string. 114 maybe?
来源:https://stackoverflow.com/questions/7384176/wcf-service-returns-incorrect-content-length-when-using-gzip-encoding