Я пытаюсь загрузить файлы, которые пользователь выбирает в браузере, на сервер Express.Я хочу потоковую передачу файлов, чтобы их не нужно было загружать в память перед их загрузкой.
Приведенный ниже код работает нормально и файлы загружаются.Однако запрос к серверу фактически не отправляется, пока не будет обработан весь файл.Если я отправлю файл размером 100 МБ, потребуется несколько секунд, чтобы индикатор выполнения полностью заполнился, и только тогда запрос поступит на сервер.Если я загружаю большие файлы, происходит сбой браузера.
Если я запускаю тот же код, меняя только ввод на fs.CreateReadStream
и удаляя биты React с узлом, он работает как положено, и файл передается в потоковом режиме.
Почему это не работает в браузере и как я могу заставить его работать?
Серверная часть очень проста и отлично работает:
router.put("/*", (req, res, next) => {
console.log("Starting to receive file");
const dst = fs.createWriteStream(fileRoot + req.params[0]);
console.log("Created file write stream");
req.pipe(dst);
req.on("end", () => {
console.log("Upload complete");
res.send("Upload complete");
});
});
Код на стороне клиента выглядит следующим образом:
sendFiles() {
const queue = [].concat(this.state.files);
let sizeSent = 0;
let fileSize = 0;
const that = this;
const reportProgress = new Transform({
transform(chunk, encoding, callback) {
sizeSent += chunk.length;
that.setState({ progress: (200 / fileSize) * sizeSent });
callback(null, chunk);
}
});
function sendNext() {
that.setState({ progress: 0 });
sizeSent = 0;
const currentFile = queue.shift();
fileSize = currentFile.size;
const hash = crypto.createHash("md5");
const hashedName = hash.update(currentFile.name).digest("hex");
console.log("sending file " + currentFile.name);
new FileReadStream(currentFile)
.pipe(crypto.createCipher("aes128", "test"))
.pipe(reportProgress)
.pipe(
request({
url: "http://localhost:8000/files/send/" + hashedName,
method: "put"
})
)
.on("error", err => {
console.log(err);
})
.on("end", function(file) {
console.log("Done");
if (queue.length > 0) {
sendNext();
} else {
that.setState({ progress: 200 });
}
});
}
sendNext();
}