提取发送到Node.js服务器的请求正文中的二进制数据(一个jpeg图像)

问题解决

你好。 我已经给了一个iPhone应用程序,作为其function的一部分,发送一个请求到服务器与请求正文中的二进制jpeg图像。 我必须find一种方法来读取二进制数据,通过socket.io发送给客户端,并将映像的副本logging到服务器上的磁盘上。

第一次尝试:

我已经尝试了几个方法,没有运气。 首先我试过这个:

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照片查看器中打开的图像。 Windows照片查看器给了我错误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我相信我有最新版本。 接下来我想知道请求是否在电话和服务器之间出现混乱。

检查请求保真度

我安装了小提琴手2 。 我设置了一个反向代理,详细在这里 。 我点击请求,然后去了hex视图。 我通过右键单击select保存字节来保存标题信息之后的字节。 我将文件命名为test.jpg,并在Windows照片查看器中打开。

节省字节

我根据“标题字节”和“主体字节”上的不同颜色select保存哪些字节,

彩色字节

这是我最终从保存这些字节的图像的一个例子

在这里输入图像描述

第二次尝试:

现在,我知道图像是在请求,我知道我可以去使用提琴手,我searchstackoverflow和谷歌,以find如何捕获请求正文。 我尝试了一堆解决scheme,但没有给我一个我可以打开的图像。

 //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"); 

据我所知,expressParser查找json键值对,因为请求体只是一堆二进制数据,它返回一个空的数组/对象(不知道哪个)。 我写了一个自定义的中间件, 在stackoverflow的这个答案的build议下,向请求对象(req)添加一个rawBodyvariables。 有几篇文章说要使用req.setEncoding('something')让Node.js知道数据是如何编码的。 我试过null base64 hexbinary

我已经上传了来自Fiddler 2的保存的请求,如果你想看看。 提琴手2请求 。 注意:我不确定要使用什么文件扩展名,所以我没有使用任何文件扩展名。

我目前卡住了。 我已经尝试了所有的解决scheme,我可以find谷歌和stackoverflow。 如果您需要,请要求澄清。 我试图尽可能详细(抱歉的长度)。 感谢您花时间阅读这些!

附注/额外

我不太了解Node.js缓冲区的工作。 如果可能,我希望能够接受这些图像的“stream”。 我不知道如何缓冲区可能会发挥一个答案,但如果它确实请尝试解释它,假设我对缓冲区知之甚less。

我还提到想要通过socket.io将图像发送到浏览器。 如果你想在你的答案中包括这第二套,将不胜感激。

如果您愿意,请提供有关您的解决scheme如何执行的信息。 (CPU或内存上或重量轻,等等)

这应该做到这一点:

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

validationcurl

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

如果这不起作用,我会用curl来testing它,以确保它不是客户端正在做一些奇怪的事情。

说到通过socket.io发送,我不会那样做,而是发送URL。 如果这不是一个选项,我想你将不得不base64编码的数据。