Answer the question
In order to leave comments, you need to log in
How to correctly send to the server and save the buffer of the uploaded file?
Hello.
I've been struggling with a problem for many hours now:
I want to send a ZIP file from my computer using NodeJS. I send the file buffer using the PUT method. And the data is being transferred. However, the file that is written to the server does not match the size of the original file.
Here's how I send a file in NodeJS :
const buffer = fs.readFileSync(`../source/archive.zip`);
const options = {
hostname: url.hostname,
port: 443,
path: url.pathname,
method: 'PUT',
headers: {
'Content-Type': 'application/zip',
'Content-Length': buffer.length
}
};
const req = https.request(options, res => {
res.on('error', err => console.log('ошибка:', err));
res.on('end', () => console.log('отправлено'));
});
req.write(buffer);
req.end();
router.put('/', (req, res, next) => {
const pathToFile = path.join(__dirname, '..', 'public', 'uploads', 'archive.zip');
let chunks = '';
req.on('data', chunk => {
chunks += chunk;
});
req.on('end', () => {
fs.writeFile(pathToFile, chunks, { encoding: 'binary' } , (err) => {
if (err) throw err;
res.send('файл сохранён');
});
});
});
writeFile
I specify the encoding in the function 'binary'
, then the size of the saved file is slightly smaller than the original one. And if I do not specify the encoding, then the size is approximately twice the size of the original. In both cases, the archive is broken and cannot be unzipped. Answer the question
In order to leave comments, you need to log in
Firstly, strings in JS are stored in memory as utf-16, which means that saving an arbitrary buffer to a string can break the data.
This is where your data breaks down:
let chunks = '';
req.on('data', chunk => {
chunks += chunk;
});
const filePath = `../source/archive.zip`;
const reader = fs.createReadStream(filePath);
const options = {
hostname: url.hostname,
port: 443,
path: url.pathname,
method: 'PUT',
headers: {
'Content-Type': 'application/zip',
'Content-Length': fs.statSync(filePath).size
}
};
const req = https.request(options, res => {
res.on('error', err => console.log('ошибка:', err));
res.on('end', () => console.log('отправлено'));
});
reader.pipe(req);
router.put('/', (req, res, next) => {
const pathToFile = path.join(__dirname, '../public/uploads/archive.zip');
const writer = fs.createWriteStream(pathToFile);
req.pipe(writer).once('error', next).once('finish', () => {
res.send('файл сохранён');
});
});
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question