首页 文章

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

提问于
浏览
3

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

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

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

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

Updated 下面是我的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 回答

  • 1

    http://www.senchalabs.org/connect/json.html . 基本上你需要编写自己的基于 connect.json() 的中间件,它管道通过像 connect.compress() 这样的非压缩流,但方向相反:http://www.senchalabs.org/connect/compress.html

    另外,请确保在请求中发送正确的 Content-Encoding 标头 .

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

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

相关问题