Переход с Windows на Linux в узле js с помощью smbget

Как получить файл, если ваш веб-сервис узла express находится на сервере 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 Я просто не смог заставить это работать, но это должно быть приемлемым вариантом.

Как вы можете сделать это из операционной системы напрямую, а не полагаться на сторонние пакеты узлов?

1 ответ

Вы можете использовать smbget (утилита linux, включенная в https://linux.die.net/man/1/smbget), а затем просто использовать узел child_process spawn для вызова функции.

Просто замените [рабочая группа], [имя пользователя], [пароль], [serveraddress] и [путь] на вашу собственную информацию здесь.

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

Приведенный выше фрагмент кода возвращает обещание. Таким образом, в узле вы можете отправить ответ на маршрут следующим образом:

 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 для отправки правильных заголовков с ответом, чтобы большинство современных веб-браузеров знали, чтобы предложить пользователю загрузить файл.

Другие вопросы по тегам