WCFサービスは、GZIPエンコーディングを使用する場合、誤ったコンテンツレングスを返します
-
29-10-2019 - |
質問
フィルタリングテキストボックスとリストボックスを含むWebページがあります。テキストボックスの変更は、Ajax要求をトリガーします。これにより、リストボックスを入力する値の配列が返されます。
返されたデータのサイズに応じて、これらの呼び出しが時々失敗することに問題がありました。小型の返されたデータはエラーが発生し、大規模なデータが返され、成功して処理されます。
この問題は、4.2を超えるjQueryバージョンを使用する場合にのみ発生します。 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);
}
}
);
2つの要素が返される場合、デバッグコンソールの内容は次のとおりです。
{"d":[{"__type":"ListEntry:#WebsitePresentationLayer","Text":"SOJACKACT0310DSN1.mpg - [SOJACKACT0310DSN1]","Value":"5565_5565"},{"__type":"ListEntry:#WebsitePresentationLayer","Text":"SOJACKACT0310DSN1Q.mpg - [SOJACKACT0310DSN1Q]","Value":"5566_5566"}]}
しかし、1つの要素が返された場合:
{"d":[{"__type":"
したがって、もちろん、「未終端の文字列定数」エラーが表示されます。
私はフィドラーを使用していくつかの調査をしました。
すべての応答(成功したものであっても)で、フィドラーはエラーを表示しました。
Fiddlerはセッション#でプロトコル違反を検出しましたN1.
コンテンツレングスの不一致:応答ヘッダーが示されています N2 バイトですが、サーバーが送信されました N3 バイト。
応答ヘッダーがサイズを示している場合 より大きい 実際のサイズよりも、結果はブラウザによって解釈される可能性があります。
応答ヘッダーがサイズを示している場合 未満 実際のサイズ、その後、ブラウザは結果を解釈できませんでした。
そこに行うことの明らかな仮定は、応答処理コードが Content-Length
ヘッダーであり、長さで規定されているものよりも多くのデータを読み取らない。
私の調査の次のステップは、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-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"
は ここ, 、しかし、私のサービス実装がこれを応答をひどくzipるリクエストとして解釈している理由を理解できません。)
// 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サービスを使用しています。
解決
まず第一に、非常に良い質問です。この質問は、私の問題の解決策に到達するのに十分な情報を私に提供しました。
私は同様の問題を抱えており、ここに修正を投稿しました。
ajax get&postリクエストはIEでnullを返していました
残りのブラウザでは正常に動作していましたが、「応答ヘッダーがnバイトを示しているのが見られましたが、サーバーはリクエストのためにfiddlerでnnバイトのメッセージを送信しました。
そこに行うことの明らかな仮定は、応答処理コードがコンテンツレングスヘッダーを読み取り、これ以上データを読み取らないことです
私もそう思います!
この場合、私は一つのことで明確でした。 何かがリクエスト/応答を改ざんしていました。私はjQueryの古いバージョンに戻りようとしました(あなたの質問で言及されているように)が、それは助けにはなりませんでした。
修理-アプリケーションのWeb構成を開き、読み上げました。ありました 「radcompressionモジュール」 テレリクからモジュールに含まれており、それを削除すると、すべてが正常に動作し始めました。
Radcompressionモジュールはバグであることが知られており、応答を圧縮することにより複数の問題を引き起こすことが知られています。
同様の問題がある場合は、リクエスト/応答を傍受している可能性のあるものをチェックしてみてください。
他のヒント
Response Header indicated 140 bytes, but server sent 254 bytes
たくさん言います。同じことは、あなたが使用するブラウザとは無関係に起こりますか?もしそうなら、IEまたはjQuery 1.4.3以降は、IEでさらに多くのバイトを読み取った後にバイトを読み取らないと言うかもしれませんが、他のブラウザはとにかくすべてのコンテンツを読み取っています。
また、応答ヘッダーがIEリクエストに対してのみ誤って形成されることも可能です(まだこれは信じられません)。次に、IEと他のブラウザリクエストとサービスコードの違いを確認する必要があります。たぶんあなたのサービスはIE要求を特に処理しますか?
最後にキャプチャされた引用マークの後にどれだけのバイトがあるかを計算することは興味深いでしょう("
)JSON文字列。 114多分?