简体   繁体   English

使用Node js从FTP服务器下载文件到客户端

[英]Download file from FTP server to client using Node js

System architecture系统架构

System consist of 3 components系统由 3 个组件组成

1: FTP server : Used to store files. 1: FTP服务器:用于存储文件。 Can only be accessed by Node.js app.只能由 Node.js 应用程序访问。 No direct access.没有直接访问。

2: Node.js : Provides an API to interact with FTP server . 2: Node.js :提供API与FTP服务器交互。 Only way to interact with FTP server .FTP 服务器交互的唯一方法。 Node.js app have no collection of files stored on FTP. Node.js 应用程序没有存储在 FTP 上的文件集合。 Only provides method to work with FTP.仅提供使用 FTP 的方法。 Node.js app should not store any file uploaded from it and download from it. Node.js 应用程序不应存储从它上传和下载的任何文件。

3: Client : A user how will upload or download a file to FTP server by using Node.js app . 3:客户端:用户如何使用Node.js 应用程序将文件上传或下载到FTP 服务器

What I have done :我所做的

I am able to download the file stored on FTP by using basic-ftp package.我可以使用basic-ftp包下载存储在 FTP 上的文件。 Here is the code for download file function.这是下载文件功能的代码。

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()
}

The file is download to the directory named /downloads on Node.js server.该文件将下载到 Node.js 服务器上名为/downloads的目录。 What I want to do actually is download the file directly to client computer.我想要做的实际上是将文件直接下载到客户端计算机。 To download the file directly to client, I have tried streaming the writeStream object from download method.要将文件直接下载到客户端,我尝试从下载方法流式传输writeStream对象。 Here is the code for that这是代码

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);
})

This does not work.这不起作用。 It always ends in error with downloading the file completely.完全下载文件总是以错误结束。

Another approach I tried is to generate a URL for the file and client will click the URL to download the file.我尝试的另一种方法是为文件生成一个 URL,客户端将单击 URL 下载文件。 Problem with this approach is the file is not complete by the time I start downloading which results in incomplete file download.这种方法的问题是我开始下载时文件不完整,导致文件下载不完整。 For example, If the size of file is 10MB and only 2 MB was download by the time client clicked the link, it will download only 2MB file not 10MB.例如,如果文件大小为 10MB,并且客户端单击链接时仅下载了 2MB,则它将仅下载 2MB 文件而不是 10MB。

Goal :目标

Download the file to client(browser) from a FTP server through Node js.通过 Node js 从 FTP 服务器下载文件到客户端(浏览器)。

Requirement :要求

Download the file stored on FTP server directly to client through Node js.通过Node js将FTP服务器上存储的文件直接下载到客户端。

Constraints :约束

Client does not have access to FTP server.客户端无权访问 FTP 服务器。

The only way to access the server is through Node js app.访问服务器的唯一方法是通过 Node js 应用程序。

You can try to indicate res as an output stream directly.您可以尝试直接将res指示为输出流。 That way you will simply redirect a stream from an ftp to a client:这样,您只需将流从 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);
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM