如果您的节点表达Web服务是在Linux服务器(ubuntu)上并且您需要从Windows服务器下载文件,那么如何检索文件?
2个有效选项:
Windows服务器不支持SFTP / SSH。有一些方法可以执行此操作(使用https://winscp.net/eng/docs/guide_windows_openssh_server和https://www.npmjs.com/package/ssh2)但这需要我们的服务器管理员在Windows上安装,而Microsoft不完全支持它。
您可以使用FTP / FTPS。有这个包:https://github.com/Atinux/node-ftps我只是无法让它工作,但它应该是一个可行的选择。
如何直接从操作系统执行此操作,而不是依赖第三方节点包?
答案 0 :(得分:2)
您可以使用smbget(https://linux.die.net/man/1/smbget附带的linux实用程序),然后使用node child_process spawn来调用该函数。
只需将您自己的信息替换为[工作组],[用户名],[密码],[服务器地址]和[路径]。
function getFile(file) {
return new Promise(function(resolve, reject) {
var tempFilePath = `/tmp/${file}`; // the linux machine
var remoteFile = require('child_process').spawn('smbget', ['--outputfile', tempFilePath, '--workgroup=[workgroup]', '-u', '[username]', '-p', '[password]', `smb://[serveraddress]/c$/[path]/[path]/${file}`]);
remoteFile.stdout.on('data', function(chunk) {
// //handle chunk of data
});
remoteFile.on('exit', function() {
//file loaded completely, continue doing stuff
// TODO: make sure the file exists on local drive before resolving.. an error should be returned if the file does not exist on WINDOWS machine
resolve(tempFilePath);
});
remoteFile.on('error', function(err) {
reject(err);
})
})
}
上面的代码片段会返回一个promise。因此,在节点中,您可以将响应发送到这样的路由:
var express = require('express'),
router = express.Router(),
retrieveFile = require('../[filename-where-above-function-is]');
router.route('/download/:file').get(function(req, res) {
retrieveFile.getFile(req.params.file).then(
file => {
res.status(200);
res.download(file, function(err) {
if (err) {
// handle error, but keep in mind the response may be partially sent
// so check res.headersSent
} else {
// remove the temp file from this server
fs.unlinkSync(file); // this delete the file!
}
});
})
.catch(err => {
console.log(err);
res.status(500).json(err);
})
}
响应将是要下载的文件的实际二进制文件。由于此文件是从远程服务器检索的,因此我们还需要确保使用fs.unlinkSync()删除本地文件。
使用res.download通过响应发送正确的标头,以便大多数现代Web浏览器知道提示用户下载文件。