将压缩的http请求主体解压缩到Node.js中的json

时间:2013-01-16 07:31:20

标签: node.js gzip windows-store-apps

我有一个连接到用Node.js编写的Web服务的Windows 8应用程序。在Windows 8一侧,我将请求主体压缩为gzip。但是在Node.js方面,我发现我的req.body类型是Object

我无法使用zlib来解析身体,因为它不是stream

我可以使用zlib来解压缩req,但我不知道如何从解压缩的流中检索req.body内容并以JSON格式解析主体。

顺便说一句,我通过Fiddler审查了我的请求,它告诉我请求正文是gzip压缩的,我可以在解压缩后通过Fiddler看到我的原始身体,所以请求应该是正确的。

更新 下面是我的Node.js应用程序

(function () {
    var express = require("express");
    var zlib = require("zlib");

    var app = express();
    var port = 12345;

    app.configure(function () {
        app.use(express.compress());
        app.use(express.bodyParser());
    });

    app.post("/test", function (req, res) {
        var request = req.body;
        req.pipe(zlib.createGunzip());

        var response = {
            status: 0,
            value: "OK"
        };
        res.send(200, response);
    });

    console.log("started at port %d", port);
    app.listen(port);
})();

以下是我的Windows商店应用代码(部分)

        private async void button1_Click_1(object sender, RoutedEventArgs e)
        {
            var message = new
            {
                Name = "Shaun",
                Value = "12345678901234567890123456789012345678901234567890"
            };
            var json = await JsonConvert.SerializeObjectAsync(message, Formatting.Indented);
            var bytes = Encoding.UTF8.GetBytes(json);

            var client = new HttpClient();
            client.BaseAddress = new Uri("http://192.168.56.1:12345/");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.ExpectContinue = false;
            var jsonContent = new JsonContent(message);
            var gzipContent = new GZipContent3(jsonContent);
            var res = await client.PostAsync("test", gzipContent);

            var dialog = new Windows.UI.Popups.MessageDialog(":)", "完成");
            await dialog.ShowAsync();
        }


        internal class GZipContent3 : ByteArrayContent
        {
            public GZipContent3(HttpContent content)
                : base(LoadGZipBytes(content))
            {
                //base.Headers.ContentType = content.Headers.ContentType;
                base.Headers.ContentType = new MediaTypeHeaderValue("x-application/x-gzip");
                base.Headers.ContentEncoding.Add("gzip");
            }

            private static byte[] LoadGZipBytes(HttpContent content)
            {
                var source = content.ReadAsByteArrayAsync().Result;
                byte[] buffer;
                using (var outStream = new MemoryStream())
                {
                    using (var gzip = new GZipStream(outStream, CompressionMode.Compress, true))
                    {
                        gzip.Write(source, 0, source.Length);
                    }
                    buffer = outStream.ToArray();
                }
                return buffer;
            }
        }


        internal class JsonContent : StringContent
        {
            private const string defaultMediaType = "application/json";

            public JsonContent(string json)
                : base(json)
            {
                var mediaTypeHeaderValue = new MediaTypeHeaderValue(defaultMediaType);
                mediaTypeHeaderValue.CharSet = Encoding.UTF8.WebName;
                base.Headers.ContentType = mediaTypeHeaderValue;
            }

            public JsonContent(object content)
                : this(GetJson(content))
            {
            }

            private static string GetJson(object content)
            {
                if (content == null)
                {
                    throw new ArgumentNullException("content");
                }
                var json = JsonConvert.SerializeObject(content, Formatting.Indented);
                return json;
            }
        }

2 个答案:

答案 0 :(得分:1)

http://www.senchalabs.org/connect/json.html。基本上,您需要根据connect.json()编写自己的中间件,这些中间件通过connect.compress()之类的非压缩流进行管道,但方向相反:http://www.senchalabs.org/connect/compress.html

另外,请确保您在请求中发送了正确的Content-Encoding标题。

如果你告诉我你到目前为止我可以帮助你。

答案 1 :(得分:1)

我正在研究类似的事情并最终登陆

function getGZipped(req, callback) {
    var gunzip = zlib.createGunzip();
    req.pipe(gunzip);

    var buffer  = [];
    gunzip.on('data', function (data) {
        // decompression chunk ready, add it to the buffer
        buffer.push(data);
    }).on('end', function () {
        //response and decompression complete, join the buffer and return
        callback(null, JSON.parse(buffer));
    }).on('error', function (e) {
        callback(e);
    });
}