Il servizio WCF restituisce una lunghezza del contenuto errata quando si utilizza la codifica GZIP

StackOverflow https://stackoverflow.com/questions/7384176

Domanda

Ho una pagina Web contenente una casella di testo di filtraggio e una casella di elenco. Le modifiche alla casella di testo innescano una richiesta AJAX, che restituisce un array di valori con cui popolare la casella di riepilogo.

A volte ho avuto problemi con queste chiamate che falliscono, dipendenti dalle dimensioni dei dati restituiti. I dati restituiti di piccole dimensioni comporterebbero un errore, i dati di grandi dimensioni sono stati restituiti ed elaborati con successo.

Questo problema si verifica solo quando utilizzo una versione jQuery maggiore di 4.2. Se uso jQuery versione 4.2, non ho il problema.


Ecco il codice della chiamata:

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

Ecco il contenuto della console di debug se vengono restituiti due elementi:

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

Ma se un elemento viene restituito:

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

Quindi, ovviamente, otteniamo un errore "costante di stringa non terminato".


Ho fatto qualche indagine usando Fiddler.

Su tutte le risposte (anche quelle di successo), Fiddler ha mostrato un errore:

Fiddler ha rilevato una violazione del protocollo nella sessione #N1.

Mismatch a lunghezza del contenuto: intestazione di risposta indicata N2 byte, ma il server ha inviato N3 byte.

Se l'intestazione della risposta indica una dimensione più grande di delle dimensioni effettive, quindi i risultati potrebbero ancora essere interpretati dal browser.

Se l'intestazione della risposta indica una dimensione meno di La dimensione effettiva, quindi il browser non è stato in grado di interpretare i risultati.

L'ovvio presupposto da fare è che il codice di gestione della risposta legge il Content-Length Intestazione e non leggono più dati di quelli previsti nella lunghezza.

Il prossimo passo nella mia indagine è confrontare le intestazioni di richiesta/risposta per JQuery versione 1.6.1 (che si interrompe) e versione 1.4.2 (che non si rompe).

JQuery 1.6.1 Richiesta di intestazione:

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

Sintesi di risposta 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

Ed ecco l'intestazione della richiesta quando uso JQuery 1.4.1. Notare che il Accept L'intestazione è diversa dal valore 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

E la risposta di nuovo a 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

Quindi la differenza ovvia è che quando la chiamata viene effettuata tramite jQuery 1.6.1 la risposta viene compressa usando GZIP e quando la chiamata viene effettuata tramite jQuery 1.4.2 la risposta non viene compressa.


Quindi ora posso fare una soluzione per lavorare, che è quello di sovrascrivere il valore predefinito Accettare Intestazione per assicurarsi che non contenga il "q=0.01" corda. (La migliore spiegazione che riesco a trovare "q=0.01" è qui, ma non riesco a capire perché l'implementazione del mio servizio sta interpretando questo come una richiesta per compensare male la risposta.)

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

Quindi, dopo tutta questa indagine, la domanda rimanente è perché esiste una disparità tra l'intestazione della lunghezza del contenuto e la lunghezza effettiva del contenuto quando la risposta è compressa GZIP?

Sto usando un servizio WCF con WebHttpBinding.

È stato utile?

Soluzione

Prima di una domanda quasi buona. Questa domanda mi ha fornito informazioni sufficienti per raggiungere una soluzione per il mio problema.

Ho avuto un problema simile e ho pubblicato la correzione qui, in modo che potesse aiutare qualcuno.

  1. Le richieste di Ajax get & post stavano restituendo null in IE

  2. Funzionava bene nel resto dei browser, ma ha visto l'intestazione di "Risposta indicava N byte, ma il server ha inviato il messaggio di nn byte in violino per la richiesta.

L'ovvio presupposto da fare è che il codice di gestione della risposta legge l'intestazione della lunghezza del contenuto e non legge più dati

Lo penso anch'io!

In questo caso, ero chiaro con una cosa. Qualcosa stava manomettendo la richiesta/risposta.Ho provato a tornare alla versione precedente di JQuery (come menzionato nella tua domanda), ma questo non ha aiutato.

Aggiustare-Ho aperto la configurazione Web della mia applicazione e ho letto. C'era un 'Modulo di RadCompression' Da Telerik incluso nei moduli e per la rimozione tutto ha iniziato a funzionare bene.

È noto che il modulo di RadCompression è un buggy e causano più problemi comprimendo la risposta.

Se hai problemi simili, prova a controllare cosa potrebbe intercettare la tua richiesta/risposta.

Altri suggerimenti

Response Header indicated 140 bytes, but server sent 254 bytes dice molto. Lo stesso accade indipendentemente dal browser che usi? In tal caso, potremmo dire che IE o JQuery 1.4.3 e più in IE non legge byte dopo aver letto tutti i byte specificati nell'intestazione della risposta, mentre altri browser leggono comunque tutto il contenuto.

È anche possibile (eppure non credo a quasi questo) che l'intestazione di risposta sia erroneamente formata solo per le richieste IE. Quindi devi esaminare le differenze tra IE e altre richieste del browser e il tuo codice di servizio. Forse i tuoi servizi gestiscono le richieste in particolare?

Sarebbe interessante calcolare la quantità di byte dopo l'ultimo marchio di citazione catturato (") nella tua stringa JSON. 114 forse?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top