Node.js从公共FTP下载文件

时间:2017-05-04 17:07:30

标签: javascript node.js ftp

您好我正在尝试编写node.js服务以从公共FTP下载文件。我可以手动执行的操作就是将ftp url粘贴到浏览器并按Enter键。然后将下载该文件。我不知道ftp的域名,用户名或密码。一个例子是这样的:

ftp://ftp.agrc.utah.gov/UtahSGID_Vector/UTM12_NAD83/TRANSPORTATION/UnpackagedData/Roads/_Statewide/Roads_shp.zip

我尝试使用node-request但它不接受ftp协议。有没有人知道这个任务的好工具?

2 个答案:

答案 0 :(得分:0)

我认为this是你想要利用的东西。

答案 1 :(得分:0)

我在 node 中构建了一个 ftp 代理,所以我不得不这样做。我做了一个函数,返回一个文件,如果文件是目录,则返回目录的索引,也许对某人有用。

它还允许用户名和密码 ftp://user:pass@like.this/

var ftp = require('ftp');
var uri = require('lil-uri')
function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on('data', chunk => chunks.push(chunk))
    stream.on('error', reject)
    stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
  })
}
async function getftpfile(url) {
  var c = new ftp();
  return await new Promise((resolve, reject) => {
    c.on('ready', function() {
      var p = decodeURI(uri(url).path());
      if (p[p.length - 1] == "/") {
        c.list(p, function(err, list) {
          if (err) throw err;
          //console.dir(list);
          function getlast(str) {
            var parts = encodeURI(str).split("/")
            return parts.pop() || parts.pop()
          }
          c.end();
          resolve(`<!DOCTYPE html>
<html>
<head>
    <title>Index of ${p}</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta content="width=640, maximum-scale=4, initial-scale=1.0" name="viewport">
    <meta content="yes" name="apple-mobile-web-app-capable">
</head>
<body>
    <h1>Index of ${p}</h1>
    <table>
        <tr>
            <th valign="top"><img alt="[ICO]" src="http://www.xray.mpe.mpg.de/icons/apache/blank.gif"></th>
            <th>Name</th>
            <th>Last modified</th>
            <th>Size</th>
            <th>Description</th>
        </tr>
        <tr>
            <th colspan="5">
                <hr>
            </th>
        </tr>
        <tr>
            <td valign="top"><img alt="[PARENTDIR]" src="http://www.xray.mpe.mpg.de/icons/apache/back.gif"></td>
            <td><a href="..">Parent Directory</a></td>
            <td>&nbsp;</td>
            <td align="right">-</td>
            <td>&nbsp;</td>
        </tr>` +
            list.map(a => `     <tr>
            <td valign="top"><img alt="${a.type=="d"?"[DIR]":"[TXT]"}" src="http://www.xray.mpe.mpg.de/icons/apache/${a.type=="d"?"folder.gif":"text.gif"}"></td>
            <td>
                <a href="${getlast(a.name)+(a.type=="d"?"/":"")}">${a.name}</a>
            </td>
            <td align="right">${a.date.toDateString()}</td>
            <td align="right">${a.size}</td>
            <td>&nbsp;</td>
        </tr>`).join('\n') + `<tr>
            <th colspan="5">
                <hr>
            </th>
        </tr>
    </table>
    <address>
        Index made by hand :/<!--yeah this was from apache, why do you ask?-->
    </address>
</body>
</html>`)
        });
      } else {
        c.get(p, function(err, stream) {
          if (err) {
            throw err
          };
          stream.once('close', function() {
            c.end();
          });
          resolve(streamToString(stream))
        });
      }
    });

    c.connect(uri(url).parts);
  })
}
//Finally get the file that you want.
getftpfile("ftp://ftp.fau.de/apache/README.html").then(console.log)