【问题标题】:Problems in writing binary data with node.js用 node.js 写二进制数据的问题
【发布时间】:2014-04-25 17:34:27
【问题描述】:

我正在尝试将请求的二进制正文写入文件并失败。该文件是在服务器上创建的,但我无法打开它。我在 Ubuntu 上收到“致命错误:不是 png”。以下是我提出请求的方式:

curl --request POST --data-binary "@abc.png" 192.168.1.38:8080

这就是我尝试将其与文件一起保存的方式。第一个 sn-p 是用于将所有数据附加在一起的中间件,第二个是请求处理程序:

中间件:

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf-8');
  req.on('data', function(chunk) { 
    req.rawBody += chunk;
  });
  req.on('end', function() {
    next();
  });
});

处理程序:

exports.save_image = function (req, res) {
  fs.writeFile("./1.png", req.rawBody, function(err) {
    if(err) {
      console.log(err);
    } else {
      console.log("The file was saved!");
    }
  });
  res.writeHead(200);
  res.end('OK\n');
};

这里有一些信息可能会有所帮助。在中间件中,如果我记录 rawBody 的长度,它看起来是正确的。我真的很困惑如何正确保存文件。我所需要的只是朝着正确的方向轻推。

【问题讨论】:

  • 你能澄清“失败”吗?文件是否存在于服务器上但内容不正确?服务器上根本不存在该文件吗?您收到错误消息吗?

标签: javascript node.js fs binary-data


【解决方案1】:

为了修复您的代码:我与 @Peter Lyons 合作,错误可能是 req.setEncoding('utf-8'); 行。

我知道以下内容不会直接问您的问题,而是使用您正在使用的 Express.js 提供的req.files 功能提出替代方案。

如果 (req.files.photo && req.files.photo.name) { // 获取文件的临时位置。 var tmp_path = req.files.photo.path;

// set where the file should actually exists - in this case it is in the "images" directory.
var target_path = './public/profile/' + req.files.photo.name;

// Move the file from the temporary location to the intended location.
fs.rename(tmp_path, target_path, function (error) {
    if (!error) {
        /*
         * Remove old photo from fs.
         * You can remove the following if you want to.
         */
        fs.unlink('./public/profile/' + old_photo, function () {
            if (error) {
                callback_parallel(error);
            }
            else {
                callback_parallel(null);
            }
        });
    }
    else {
        callback_parallel(error);
    }
});

}

【讨论】:

  • 这也是我的偏好,但我必须使用提供给我的外部数据源,这是我无法控制的。感谢您的回答。
  • req.files 属性将被定义,如果客户端使用带有 enctype="multipart/form_data" 的 http 表单,然后在该表单上发出提交。如果客户端使用不同的机制,例如 AJAX 调用,则不会设置此类属性。
【解决方案2】:

这是一个完整的快递应用程序。我用curl --data-binary @photo.jpg localhost:9200 打了它,效果很好。

var app = require("express")();
var fs = require("fs");
app.post("/", function (req, res) {
  var outStream = fs.createWriteStream("/tmp/upload.jpg");
  req.pipe(outStream);
  res.send();
});
app.listen(9200);

我只是将请求直接传送到文件系统。至于您的实际问题,我的第一个猜测是req.setEncoding('utf-8');,因为 utf-8 用于文本数据而不是二进制数据。

【讨论】:

  • 是的,它正在工作。但是,在某些情况下,我只能得到部分图像。这通常发生在远程连接上。
  • 嗯,这可能不是您可以在代码中解决的问题。如果网络不传递数据包,那么您在应用程序代码中所做的任何事情都无法神奇地合成它们。您需要深入了解到底出了什么问题,但这可能不是代码问题。
  • 如果不匹配拒绝,也许您应该根据传入数据检查内容长度标头。
  • @FaridNouriNeshat 如果我拒绝一个块,我认为我将无法组装完整的图像。我正在查看节点流。彼得的回答可能对我有用。
  • 我的意思是拒绝整个请求,如果看到发出的结束事件但接收到的内容不完整,所以你只是假设请求结束了一半并且不进一步处理它,为用户提供服务一个 4xx 状态码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
相关资源
最近更新 更多