#javascript #node.js #ftp
#javascript #node.js #ftp
Вопрос:
Архитектура системы
Система состоит из 3 компонентов
1: FTP-сервер: используется для хранения файлов. Может быть доступен только Node.js приложение. Нет прямого доступа.
2: Node.js : Предоставляет API для взаимодействия с FTP-сервером. Единственный способ взаимодействия с FTP-сервером. Node.js приложение не имеет коллекции файлов, хранящихся на FTP. Предоставляет только метод для работы с FTP. Node.js приложение не должно хранить какие-либо загруженные из него файлы и скачивать их с него.
3: Клиент: пользователь, как будет загружать или загружать файл на FTP-сервер с помощью Node.js приложение.
Что я сделал:
Я могу загрузить файл, хранящийся на FTP, с помощью basic-ftp
package. Вот код для функции загрузки файла.
async function downloadFile(folderPath, fileName, writeStream) {
console.log(folderPath);
console.log(fileName);
const client = new ftp.Client()
// client.ftp.verbose = true
try {
await client.access({
'host': process.env.FTP_HOST,
'user': process.env.FTP_USER,
'password': process.env.FTP_PASSWORD,
});
await client.ensureDir(folderPath);
await client.downloadTo(writeStream, fileName);
}
catch(err) {
console.log(err)
}
client.close()
}
Файл загружается в каталог с именем /downloads
на Node.js сервер. На самом деле я хочу загрузить файл непосредственно на клиентский компьютер. Чтобы загрузить файл непосредственно на клиент, я попробовал потоковую writeStream
передачу объекта из метода загрузки. Вот код для этого
app.post("/download/file", urlencodedParser, (req, res, next) => {
var writeStream = fs.createWriteStream('./downloads/' req.body.fileName);
writeStream.on("data", (data) => {
res.write(data);
})
writeStream.on("close", () => {
res.end()
})
res.setHeader('Transfer-Encoding', 'chunked');
downloadFile(req.body.folderName, req.body.fileName, writeStream);
})
Это не работает. Это всегда заканчивается ошибкой при полной загрузке файла.
Другой подход, который я попробовал, — сгенерировать URL-адрес для файла, и клиент нажмет на URL-адрес, чтобы загрузить файл. Проблема с этим подходом заключается в том, что файл не завершен к моменту начала загрузки, что приводит к неполной загрузке файла. Например, если размер файла составляет 10 МБ и к моменту нажатия клиентом ссылки было загружено только 2 МБ, он загрузит только 2 МБ файла, а не 10 МБ.
Цель:
Загрузите файл на клиент (браузер) с FTP-сервера через узел js.
Требование:
Загрузите файл, хранящийся на FTP-сервере, непосредственно на клиент через узел js.
Ограничения:
Клиент не имеет доступа к FTP-серверу.
Единственный способ получить доступ к серверу — через приложение Node js.
Комментарии:
1. Здравствуйте, итак, по сути, вы хотите «соединить» сервер (ИСПОЛЬЗУЯ NodeJS) С клиентом, чтобы клиент никогда не видел ОСНОВНОЙ сервер, только сервер NodeJS, не так ли?
2. ДА. Я хочу перейти с сервера НА клиент.
3. Я не тестировал это, но я думаю, что это можно сделать с помощью модуля «net» из nodejs, вы могли бы просто «передать» соединение с сервера клиенту, и сервер будет видеть только сервер nodejs, а клиент будет видеть только сервер nodejs! попробуйте…
4. вам просто нужно вручную включить учетные данные FTP при подключении перед каналом…
Ответ №1:
Вы можете попытаться указать res
в качестве выходного потока напрямую. Таким образом, вы просто перенаправите поток с ftp на клиент:
async function downloadFile(fileName, writeStream) {
console.log(fileName);
const client = new ftp.Client()
// client.ftp.verbose = true
try {
await client.access({
'host': process.env.FTP_HOST,
'user': process.env.FTP_USER,
'password': process.env.FTP_PASSWORD,
});
await client.downloadTo(writeStream, fileName);
}
catch(err) {
console.log(err)
}
client.close()
}
app.post("/download/file", urlencodedParser, (req, res, next) => {
downloadFile(req.body.fileName, res);
})