首页 文章

在发送到Node.js服务器的请求主体中提取二进制数据(jpeg图像)

提问于
浏览
7

要解决的问题

你好 . 我得到了一个iPhone应用程序,作为其功能的一部分,在请求正文中向服务器发送带有二进制jpeg图像的请求 . 我必须找到一种方法来读取二进制数据,通过socket.io将其发送到客户端,并将映像的副本记录到服务器上的磁盘 .

首先尝试:

我尝试了一些没有运气的方法 . 首先我尝试了这个:

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
console.log("Request In");
    var body = '';
    req.on('data', function (data) {
        body += data;
    });
    req.on('end', function () {
        fs.writeFile("./1.jpeg", body, function(err) {
        if(err) {
            console.log(err);
           } else {
            console.log("The file was saved!");
     }
});
    });
res.writeHead(200, {'Content-Type':'text/plain'});
res.end('Image Saved!');
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');

这没用 . 我无法获得可在Windows Photo Viewer中打开的图像 . Windows Photo Viewer给了我错误 Windows Photo Viewer can't open this picture because either Photo Viewer doesn't support this file format, or you don't have the latest updates to Photo Viewer 我确定我有最新版本 . 我接下来想知道请求是否在手机和服务器之间搞砸了 .

检查请求保真度

我安装了Fiddler 2 . 我设置了一个反向代理,详细here . 我点击了请求,然后转到了十六进制视图 . 我通过右键单击选择保存字节来保存 Headers 信息后的字节 . 我将文件命名为test.jpg,它在Windows Photo Viewer中打开就好了 .

saving bytes

我根据“ Headers 字节”和“正文字节”上的不同颜色选择保存哪些字节

colored bytes

这是我最终从保存这些字节得到的图像示例

enter image description here

第二次尝试:

现在,我知道图像在请求中,我知道我可以使用fiddler,我搜索stackoverflow和谷歌找到如何捕获请求正文 . 我尝试了一堆解决方案,但没有人给我一张我可以打开的图片 .

//Express.js
var express = require('express');
var app = express();
var fs = require('fs');

app.configure(function(){
    app.use(express.bodyParser());
    app.use(function(req, res, next) {
        req.rawBody = '';
        // req.setEncoding('base64');
        req.setEncoding(null);
        req.on('data', function(chunk) { 
            req.rawBody += chunk;
        });
        req.on('end', function() {
            next();
        });
    });
});

app.listen(3000);

app.get('*', function(req, res){
    res.writeHead(200);
    res.end('Hello World');
    console.log(req.rawBody);
});

app.put('*',  function(req, res){
    console.log("putted");
    res.writeHead(200);
    res.end('Hello World');
    fs.writeFile("./1.jpg", req.rawBody, function(err) {
        if(err) {
            console.log(err);
        } else {
            console.log("The file was saved!");
        }
    });
    console.log(req.headers);
    console.log(req.params);
    console.log(req.body);
});
console.log("running");

据我所知,express bodyParser查找json键值对,因为请求体只是一堆二进制数据,它返回一个空数组/对象(不确定哪个) . 我编写了自定义中间件,它在this answer on stackoverflow的建议下将rawBody变量添加到请求对象(req) . 一些文章说使用 req.setEncoding('something') 让Node.js知道数据是如何编码的 . 我试过 null base64 hexbinary .

我已经上传了来自Fiddler 2的已保存的请求,如果您想查看一下 . Fiddler 2 Request . 注意:我没有't sure what file extension to use so I didn' t使用任何文件扩展名 .

I am currently stuck. 我已经尝试过在google和stackoverflow上找到的所有解决方案 . 如果需要,请询问澄清 . 我试图尽可能详细(抱歉长度) . Thank you for taking the time to read this far!

Side Note / Extra

我对Node.js缓冲区的工作知之甚少 . 如果可能的话,我希望能够接受这些图像的“流” . 我不知道缓冲区可能会如何影响答案,但如果确实如此,请尝试解释它,假设我对缓冲区知之甚少 .

我还提到想通过socket.io将图像发送到浏览器 . 如果您想在答案中包含第二组,我们将不胜感激 .

如果您愿意,请提供有关您的解决方案如何执行的信息 . (重CPU或内存或亮灯等)

1 回答

  • 4

    这应该这样做:

    var http = require('http');
    var fs = require('fs');
    
    var app = http.createServer(function (req, res) {
      req.pipe(fs.createWriteStream(__dirname + req.url));
    
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('OK!');
    });
    
    app.listen(3000);
    

    已通过 curl 验证:

    curl -H 'Content-Type: application/octet-stream' --data-binary @file.jpg localhost:3000/foo.jpg
    

    如果这不起作用,我会用curl测试它,以确保它不是客户端做了一些奇怪的事情 .

    当它通过socket.io发送时,我不会选择't do that, but send the URL instead. If that',我猜你必须对数据进行编码 .

相关问题