Я пытаюсь передать fetch некоторые двоичные данные (MP3) с сервера, а затем сохранить их в файле:
var fs = require ('fs');
var fetch = require ('node-fetch');
fetch (
audioUrl,
{
method: 'GET',
headers: { 'Accept': '*/*' }
}
)
.then ((res) => res.blob())
.then ((blob) => {
console.info ('Blob size: ', blob.size);
fs.writeFile (
`filename.mp3`,
blob, // BUG HERE
(err) => {
if (err) {
console.info (`Error writing audio ${audioIdx}`, err);
}
}
);
})
Проблема отмечена как BUG HERE. Я передаю BLOB-объект fs, который не понимает BLOB-объекты и просто записывает [object Blob]. Я также пробовал следующее:
blob // writes [object Blob]
new Uint8Array (blob) // writes empty file
Buffer.from (new Uint8Array (blob)) // writes empty file
new Buffer (blob, 'binary') // Error: argument is not a Buffer
Ничего из вышеперечисленного не работает. Как это сделать правильно?
Обратите внимание, что я регистрирую blob.size перед вызовом writeFile. blob.size показывает правильный размер, поэтому fetch кажется успешным.
узел-выборка. Обновлю вопрос.





Итак, из Документы MDN Blob - это не буфер, а это то, что вам нужно для записи в файловую систему.
Я думаю, вам может быть лучше просто получить буфер из ответа, например:
.then(res => res.buffer())
.then(/* write your file here */)
хотя, в зависимости от размера файлов, лучше всего вообще пропустить функцию .writeFile и вместо этого использовать конвейерные потоки.
Это сработало! Спасибо! Файлы не очень большие, поэтому я полагаю, что потоковая передача не требуется.
Вы можете транслировать ответ в файл с помощью fs.createWriteStream.
fetch(
audioUrl,
{
method: 'GET',
headers: { 'Accept': '*/*' }
}
).then(res => {
new Promise((resolve, reject) => {
const dest = fs.createWriteStream(`filename.mp3`);
res.body.pipe(dest);
res.body.on('end', () => resolve());
dest.on('error', reject);
})
});
Это лучше, чем .buffer() или .arrayBuffer() (по крайней мере, для больших файлов)
какую библиотеку выборки вы используете?