フィルタリング テキスト ボックスとリスト ボックスを含む 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":"
したがって、当然、「Unterminated String Constant」エラーが発生します。
私はフィドラーを使用していくつかの調査を行いました。
すべての応答 (成功したものも含む) で、fiddler はエラーを表示しました。
Fiddler は、セッション # n1でプロトコル違反を検出しました。
Content-Length の不一致: 応答ヘッダーは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 経由で行われる場合、応答は圧縮されないことです。
これで、デフォルトのAcceptヘッダーをオーバーライドして、文字列が含まれないようにする 回避策を実行できます
"q=0.01"
。(私が見つけることができる最良の説明"q=0.01"
はhere ですが、サービスの実装がこれを、応答を圧縮するための要求として解釈している理由がわかりません。)
// 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 サービスを使用しています。