使用Node.js的easy-ftp上传SFTP文件无报错但失败,求排查原因
Hey there! Let's figure out why your SFTP upload isn't working even though FileZilla handles it perfectly. Since you're getting no errors, the issue is probably hiding in either the library's limitations, your code's flow, or some overlooked configuration detail. Here are the most likely fixes:
1. Verify if easy-ftp actually supports SFTP
First things first: SFTP and FTP/FTPS are completely different protocols—SFTP runs over SSH, while FTP uses its own separate protocol stack. Many "FTP" libraries don't include SFTP support by default, and a quick check of the easy-ftp docs suggests it only supports FTP and FTPS, not SFTP. If that's the case, this library won't work for your use case no matter what configuration you use.
2. Double-check every configuration detail against FileZilla
Even if you think settings match, it's worth verifying these specifics:
- Port number: FileZilla defaults to 22 for SFTP—does your code explicitly set
port: 22? Some libraries default to FTP's port 21, which would fail silently if the server doesn't listen there. - Remote path: Are you using an absolute path (like
/public_html/myfile.txt) instead of a relative one? FileZilla might be navigating to a default directory automatically, but your code needs the full path. - Local file path: If using a relative path, make sure Node.js is running from the correct working directory. You can confirm with
console.log(process.cwd())to see if it matches where your local file is stored. - Special characters in credentials: If your password has symbols like
@,$, or\, make sure they're properly escaped in your code (e.g., using backslashes for special characters in strings).
3. Enable debug logging and error handling
Most libraries suppress non-critical logs by default. Add event listeners to catch hidden errors or connection details:
const EasyFtp = require('easy-ftp'); const ftp = new EasyFtp(); // Catch any hidden errors ftp.on('error', (err) => { console.error('FTP Error:', err); }); // Enable debug mode to see connection flow ftp.on('debug', (message) => { console.log('Debug Log:', message); }); // Your existing upload code here
This might reveal issues like permission denied on the remote server, a non-existent remote directory, or a failed SSH handshake that wasn't triggering a top-level error.
4. Ensure your code waits for the upload to complete
If you're using Promises, make sure you're handling .catch() to catch any silent rejections. For callback-based code, ensure you're not closing the connection early or exiting the program before the upload finishes:
Callback example:
ftp.upload('./local-file.txt', '/remote/path/file.txt', (err) => { if (err) { console.error('Upload failed:', err); } else { console.log('Upload successful!'); } // Always close the connection after the operation completes ftp.close(); });
Promise example:
ftp.upload('./local-file.txt', '/remote/path/file.txt') .then(() => { console.log('Upload done!'); ftp.close(); }) .catch((err) => { console.error('Upload error:', err); ftp.close(); });
If your Node.js process exits before the upload finishes (e.g., if there's no code keeping it alive), the transfer will abort silently.
5. Switch to a dedicated SFTP library
If easy-ftp doesn't support SFTP, or you can't resolve the issue, use a library built specifically for SFTP like ssh2-sftp-client. It's well-maintained, supports Promises natively, and provides clear error messages. Here's a quick example:
const Client = require('ssh2-sftp-client'); const sftp = new Client(); sftp.connect({ host: 'your-server-host', port: 22, username: 'your-username', password: 'your-password' }) .then(() => sftp.put('./local-file.txt', '/remote/path/file.txt')) .then(() => { console.log('File uploaded successfully!'); return sftp.end(); }) .catch((err) => { console.error('SFTP Error:', err); sftp.end(); });
This should give you explicit feedback if something goes wrong, making debugging much easier.
内容的提问来源于stack exchange,提问作者kamome

