节点 - 无法在服务器上打开上载的jpg

时间:2017-08-22 19:07:12

标签: node.js jpeg fs

更新 感谢@robertklep和@vallo指出我没有正确解析多部分请求。

这是更新后的服务器代码,其中包含一些来自Busboy的重新编写的示例代码:

'use strict';

// Require
var http    = require('http');
var Busboy  = require('busboy');
var fs      = require('fs');

// Server
var server = http.createServer(function(request, response) {
  if (request.method === 'POST') {
    var busboy = new Busboy({ headers: request.headers });
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
      file.pipe(fs.createWriteStream(`../db/images/${filename}`));
    });
    busboy.on('finish', function() {
      response.writeHead(200, { 'Connection': 'close' });
      response.end("That's all folks!");
    });
    return request.pipe(busboy);
  }
  response.writeHead(404);
  response.end();
});
server.listen(8000, '192.168.7.25', () => {});

我正在尝试将jpg发布到端点,但无法打开生成的图像:

  

无法打开文件“image_copy.jpg”。它可能会损坏或   使用预览无法识别的文件格式。

一些背景知识:

  • 所有内容(服务器,存储)都在本地托管
  • 由于微控制器板上的存储限制,决定仅使用http和fs等本机节点模块
  • 使用表单数据,因为它可以减轻多部分表单和上传的痛苦,并设置正确的请求标题

以下是一些分为两个脚本的示例代码:

服务器

'use strict';

// Require
var http = require('http');

// Server
var server = http.createServer((request, response) => {
    var body = [];
    request.on('data', function(chunk) {
      body.push(chunk);
    });
    request.on('end', function() {
        saveImage(Buffer.concat(body),null);
        response.statusCode = 200;
        response.end('thanks')
    });
});
server.listen(8000, '192.168.7.25', () => {});


// Process
function saveImage(data,callback) {
    var fs = require('fs');
  fs.writeFile('../db/images/image_copy.jpg', data, function(err) {});
}

客户端

'use strict';

// Require
var FormData    = require('form-data');
var fs          = require('fs');
var http        = require('http');

// Vars
var form = new FormData();

// Process
form.append('my_file', fs.createReadStream('/temp/1.jpg'));
var request = http.request({
  hostname: '192.168.7.25',
  port: 8000,
  path: '/api/premises/v1/image',
  method: 'POST',
  headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
  console.log(res.statusCode);
});

执行后,jpg上传并保存到正确的文件位置(并且文件大小与源jpg相同),但新图像无法打开。

即使我将传入的块编码为二进制并将fs.writeFile上的编码设置为二进制,我也会得到类似的结果。

我做错了什么?谢谢!

1 个答案:

答案 0 :(得分:1)

客户端正在以<!-- Scripts --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- HTML --> <table class="tablecontact__body" border="1"> <tr> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>3</td> <td>3</td> <td>3</td> </tr> <tr> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>5</td> <td>5</td> <td>5</td> <td>5</td> </tr> </table>格式上传,这种格式可以包含文件数据等。

但是,这意味着服务器应解析此格式以提取文件数据。现在,服务器只是逐字地接收请求主体并将其写入文件。

multipart/form-data模块可以为您提供帮助,其中一个使用示例向您展示了如何与multiparty联系起来:https://github.com/pillarjs/multiparty#usage

http.Server

使用它,您可以从(我认为)var multiparty = require('multiparty'); var http = require('http'); var util = require('util'); http.createServer(function(req, res) { // parse a file upload var form = new multiparty.Form(); form.parse(req, function(err, fields, files) { res.writeHead(200, {'content-type': 'text/plain'}); res.write('received upload:\n\n'); res.end(util.inspect({fields: fields, files: files})); }); }).listen(8000); 中提取文件数据并将其写入文件。