'How to download file over FTP in NodeJS?
I want to download file using absolute FTP URL, like ftp://host:port/dir/file.extension
I've tried node-libcurl, wget, wget-improved, request. All failed saying that the protocol must be either HTTP or HTTPS.
There are FTP clients available for Node (available on npmjs). But, as per their documentation, they require creating a connection to FTP Server, change directory and then download it.
Is there any simple solution?
Solution 1:[1]
I will outline a simple approach here (and no complete solution with code!). FTP is based upon TCP with a simple human readable protocol. In order to fetch a file from an FTP server you need to do the following:
- Create a TCP socket using
net.Socket - Use
socket.connectto connect to your FTP server on port 21 - Communicate with the server using
socket.writeto send data andsocket.on('data')to read data
An example of FTPs protocol for a simple file retrieval is provided in this blog post and can be summarized as follows:
- Connect to server using
net.Socket.connect - Set user with
USERcommand - Authenticate with
PASS - Go to desired directory using
CWD - Change to passive mode using
PASV - Read server reply to find out IP and port to connect to in order to fetch the file
- Open another socket on IP and port of previous step
- VoilĂ !
Solution 2:[2]
You can use node-libcurl, I don't know exactly how you did it, but here is some working code.
var Curl = require( 'node-libcurl' ).Curl,
Easy = require( 'node-libcurl' ).Easy,
path = require( 'path' ),
fs = require( 'fs' );
var handle = new Easy(),
url = 'ftp://speedtest.tele2.net/1MB.zip',
// Download file to the path given as first argument
// or to a file named 1MB.zip on current dir
fileOutPath = process.argv[2] || path.join( process.cwd(), '1MB.zip' ),
fileOut = fs.openSync( fileOutPath, 'w+' );
handle.setOpt( Curl.option.URL, url );
handle.setOpt( Curl.option.WRITEFUNCTION, function( buff, nmemb, size ) {
var written = 0;
if ( fileOut ) {
written = fs.writeSync( fileOut, buff, 0, nmemb * size );
}
return written;
});
handle.perform();
fs.closeSync( fileOut );
The repository currently has one example showing how to download a file using wildcard matching, I just changed the URL to point directly at the file, and removed the WILDCARDMATCH and CHUNK_*_FUNCTION options.
Solution 3:[3]
Anyone wanting to have simple single line solution that in addition to FTP would also work with FTPS and SFTP, you can try ftp-any-get
import { getFile } from "@tpisto/ftp-any-get"
async function main() {
// Fetch from FTP server
let ftpFile = await getFile("ftp://demo:[email protected]/my-file.txt");
// Fetch from FTP server using TLS
let ftpsFile = await getFile("ftps://demo:[email protected]/my-file.txt");
// Fetch file using SFTP. SFTP runs over the SSH protocol.
let sftpFile = await getFile("sftp://demo:[email protected]/my-file.txt");
}
main();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yan Foto |
| Solution 2 | suther |
| Solution 3 | tpisto |
