节点 - 无法在服务器上打开上传的 jpg
Node - Uploaded jpg cannot be opened on server
更新
感谢@robertklep 和@vallo 指出我没有正确解析多部分请求。
这是更新后的服务器代码,其中包含 Busboy 中的一些 re-worked 示例代码:
'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', () => {});
我正在尝试 post 将 jpg 发送到端点,但生成的图像无法打开:
The file “image_copy.jpg” could not be opened. It may be damaged or
use a file format that Preview doesn’t recognize.
一些背景:
- 一切(服务器、存储)都在本地托管
- 由于微控制器板上的存储限制,已决定仅使用 http 和 fs 等本机 Node 模块
- 我正在使用 form-data,因为它减轻了 multi-part 表单和上传的痛苦,并设置了正确的请求 headers
下面是一些分成两个脚本的示例代码:
服务器
'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 上的编码设置为二进制,我也会得到类似的结果。
我做错了什么?谢谢!
客户端正在以 multipart/form-data
格式上传,该格式可以包含文件数据等。
但是,这意味着服务器应该解析这种格式来提取文件数据。现在,服务器只是逐字获取请求正文并将其写入文件。
multiparty
模块可以帮助您,它的一个用法示例向您展示了如何将它与 http.Server
连接起来:https://github.com/pillarjs/multiparty#usage
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);
使用它,您可以从(我认为)files.my_file
中提取文件数据并将其写入文件。
更新 感谢@robertklep 和@vallo 指出我没有正确解析多部分请求。
这是更新后的服务器代码,其中包含 Busboy 中的一些 re-worked 示例代码:
'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', () => {});
我正在尝试 post 将 jpg 发送到端点,但生成的图像无法打开:
The file “image_copy.jpg” could not be opened. It may be damaged or use a file format that Preview doesn’t recognize.
一些背景:
- 一切(服务器、存储)都在本地托管
- 由于微控制器板上的存储限制,已决定仅使用 http 和 fs 等本机 Node 模块
- 我正在使用 form-data,因为它减轻了 multi-part 表单和上传的痛苦,并设置了正确的请求 headers
下面是一些分成两个脚本的示例代码:
服务器
'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 上的编码设置为二进制,我也会得到类似的结果。
我做错了什么?谢谢!
客户端正在以 multipart/form-data
格式上传,该格式可以包含文件数据等。
但是,这意味着服务器应该解析这种格式来提取文件数据。现在,服务器只是逐字获取请求正文并将其写入文件。
multiparty
模块可以帮助您,它的一个用法示例向您展示了如何将它与 http.Server
连接起来:https://github.com/pillarjs/multiparty#usage
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);
使用它,您可以从(我认为)files.my_file
中提取文件数据并将其写入文件。