J'ai vu un tas de questions similaires à cette demande avant, mais je n'ai pas trouvé un qui décrit mon problème actuel exactement, donc voilà:
J'ai une page qui charge un grand (entre 0,5 et 10 MO) document JSON via AJAX, de sorte que le code côté client peut la traiter. Une fois le fichier chargé, je n'ai pas de problèmes que je ne m'attends pas. Cependant, il faut un temps de téléchargement, j'ai donc essayé de tirer parti de la XHR Progrès de l'API pour rendre une barre de progression pour indiquer à l'utilisateur que le document est en cours de chargement. Cela a bien fonctionné.
Puis, dans un effort pour accélérer les choses, j'ai essayé de la compression de la sortie sur le côté serveur via gzip et deflate. Cela a fonctionné aussi, avec d'énormes gains, cependant, ma barre de progression de l'arrêt de travail.
J'ai regardé dans le problème pendant un certain temps et a constaté que si un bon Content-Length
d'en-tête n'est pas envoyé avec la demande AJAX ressources, l' onProgress
gestionnaire d'événement ne peut pas fonctionner comme prévu car il ne sait pas combien de temps le téléchargement il est. Lorsque cela se produit, une propriété appelée lengthComputable
est définie à l' false
sur l'objet de l'événement.
Ce sens faite, alors, j'ai essayé de réglage de l'en-tête de manière explicite à la fois décompressé et par la compression de la longueur de la sortie. Je peux vérifier que l'en-tête est envoyé, et j'ai pu vérifier que mon navigateur sait comment décompresser le contenu. Mais l' onProgress
gestionnaire de rapports toujours lengthComputable = false
.
Donc ma question est: est-il un moyen de gzippé/dégonflé contenu avec l'AJAX Progrès de l'API? Et si oui, que fais-je tort?
C'est la façon dont la ressource apparaît dans le Chrome Réseau de bord, montrant que la compression de travail:
Ce sont pertinentes demande des en-têtes, montrant que la demande est AJAX et qu' Accept-Encoding
correctement:
GET /dashboard/reports/ajax/load HTTP/1.1
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.99 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Ces sont les réponse des en-têtes, montrant que l' Content-Length
et Content-Type
sont définies correctement:
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Encoding: deflate
Content-Type: application/json
Date: Tue, 26 Feb 2013 18:59:07 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
P3P: CP="CAO PSA OUR"
Pragma: no-cache
Server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g PHP/5.4.7
X-Powered-By: PHP/5.4.7
Content-Length: 223879
Connection: keep-alive
Pour ce que ça vaut, j'ai essayé cela sur un standard (http) et sécurisé (https) de connexion, ni de différences: le contenu se charge correctement dans le navigateur, mais n'est pas traité par les Progrès de l'API.
Par Adam de la suggestion, j'ai essayé de commutation du côté serveur pour l'encodage gzip, sans succès ou de changement. Voici les en-têtes de réponse:
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 04 Mar 2013 22:33:19 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
P3P: CP="CAO PSA OUR"
Pragma: no-cache
Server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g PHP/5.4.7
X-Powered-By: PHP/5.4.7
Content-Length: 28250
Connection: keep-alive
Je le répète: le contenu est téléchargé et décodé correctement, c'est juste les progrès de l'API que je vais avoir des ennuis avec.
Par Bertrand demande, voici la demande:
$.ajax({
url: '<url snipped>',
data: {},
success: onDone,
dataType: 'json',
cache: true,
progress: onProgress || function(){}
});
Et voici l' onProgress
gestionnaire d'événement que j'utilise (il n'est pas trop fou):
function(jqXHR, evt)
{
// yes, I know this generates Infinity sometimes
var pct = 100 * evt.position / evt.total;
// just a method that updates some styles and javascript
updateProgress(pct);
});