web-dev-qa-db-fra.com

Compression des données de publication HTTP envoyées depuis le navigateur

Je veux envoyer des données compressées POST avec Javascript à un serveur que je contrôle. Existe-t-il un moyen de laisser la couche HTTP gérer la compression.

J'envoie du JSON. Si je définis le type de contenu sur GZIP/dégonfler, le navigateur le compressera-t-il automatiquement, puis Apache avec le mod de dégonflage le décompressera-t-il automatiquement afin que mon application n'ait pas à penser aux données compressées?

Je sais que cela peut fonctionner dans l'autre sens, mais est-il possible de le faire fonctionner de cette façon?

35
Derek Organ

Le navigateur encodera-t-il automatiquement vos données pour vous? La réponse courte est non.

La réponse longue est que certains agents utilisateurs peuvent faire des choses comme ça, mais vous certainement ne pouvez pas vous y fier. Les documents Apache mod_deflate indiquent:

certaines applications spéciales prennent en charge la compression des demandes, par exemple certains clients WebDAV.

Donc, non, ça ne marchera pas. Vous devrez générer vous-même le message de requête HTTP approprié. L'en-tête approprié dans ce cas est Content-Encoding: gzip Et NON Content-Type: Car le contenu lui-même est application/json, Vous cherchez simplement à coder le corps d'entité de votre message de requête HTTP pour le transport .

Notez que vous devez également ajouter l'en-tête Content-Length: Approprié en spécifiant la taille en octets du corps de l'entité de message après la compression -OU- envoyer votre message HTTP à l'aide de Transfer-Encoding: chunked Et renoncer à la spécification de longueur de contenu.

Côté réception, vous pouvezdemandez à mod_deflate D'utiliser un filtre d'entrée pour décompresser les informations:

<Location /dav-area>
SetInputFilter DEFLATE
</Location>

C'est un peu lourd si vous ne recevez que des corps de message compressés pour quelques ressources. Au lieu de cela, vous devez probablement simplement utiliser le script côté client pour vérifier l'en-tête Content-Encoding: gzip Et décompresser le corps de la demande manuellement. Comment faire cela en PHP, par exemple, est une toute autre question. Si vous avez besoin de détails pour cela, vous devez poster une autre question.

70
rdlowrey

C'est possible, mais je vous déconseille fortement d'accepter les données compressées entrantes sur votre serveur. La raison principale est d'empêcher votre serveur de se faire bombardement gzip . Il n'est généralement pas possible de savoir à quoi ressemblent les données non compressées avant de les décompresser, de sorte qu'un utilisateur peut vous envoyer une demande Web qui ressemble à 1 Ko ou 1 Mo de données inoffensives mais correspond en réalité à 100 Go de données, puis à votre site Web. serveur (nginx ou Apache) se bloque les 10 minutes suivantes en essayant de tout décompresser, finissant par manquer de mémoire/verrouillage.

9
Michael Butler

Je viens de le faire en utilisant https://github.com/dankogai/js-deflate Cependant, les données postérieures pour une raison quelconque supprimeront les signes + et les remplaceront par des espaces.

Pour envoyer les données via javascript:

params.mapdata=  btoa(RawDeflate.deflate(JSON.stringify(mapdata)));

Pour recevoir les données via php:

$value = gzinflate(base64_decode(preg_replace('/\s/', '+',$value)));
0
Darren Johnston