nodejs连接ftp上传下载实现方法详解【附:踩坑记录】

依赖

//ftp 模块是目前找到的还不错的,对于ftp的基本功能都支持
npm install ftp

连接ftp

const ftp = require('ftp');//连接FTP
const client = new ftp();
client.on('ready',()=>{
    console.log('ftp client is ready');
});
client.connect({
    host : '***.***.***.***',
    port : '****',
    user : '***',
    password : '***',
    keepalive : 1000
});

ftp 获取列表 list

//列出目标目录
function list(dirpath){
    return new Promise((resolve,reject)=>{
        client.list((err,files)=>{
            resolve({err : err,files : files});
        })
    });
}
async function test (){
    //list 列表功能
    let {err,files} = await list();
    if(err){
        console.log(err);
        return
    }
    console.log(`获得文件列表:`+files.length);
    console.log(files);
}
test();

ftp 目录切换

//切换目录
function cwd(dirpath){
    return new Promise((resolve,reject)=>{
        client.cwd(dirpath,(err,dir)=>{
            resolve({err : err,dir : dir});
        })
    });
}

FBI WARNING : 这里提醒下,在本示例中的所有代码都在同一个文件中,后面会给出完整示例代码。

有了目录切换,那么在list函数中的dirpath就可以使用啦。如下:

//列出目标目录
//列出目标目录
async function list(dirpath){
    let {err : ea,dir } = await cwd(dirpath);
    return new Promise((resolve,reject)=>{
        client.list((err,files)=>{
            resolve({err : err,files : files})
        })
    });
}

ftp下载文件

//下载文件
async function get(filePath){
    const dirpath = path.dirname(filePath);
    const fileName = path.basename(filePath);
    let {err : ea,dir} = await cwd(dirpath);
    return new Promise((resolve,reject)=>{
        client.get(fileName,(err,rs)=>{
            let ws = fs.createWriteStream(fileName);
            rs.pipe(ws);
            resolve({err : err});
        });
    });
}

ftp上传文件

//将文件上传到ftp目标地址
async function put(currentFile,targetFilePath){
    const dirpath = path.dirname(targetFilePath);
    const fileName = path.basename(targetFilePath);
    const rs = fs.createReadStream(currentFile);
    let {err : ea,dir} = await cwd(dirpath);//此处应对err做处理
    if(ea){
        return Promise.resolve({err : ea});
    }
    return new Promise((resolve,reject)=>{
        client.put(rs,fileName,(err)=>{
            resolve({err : err});
        })
    });
}

完整代码

const ftp = require('ftp');//连接FTP
const path = require('path');
const client = new ftp();
const fs = require('fs');
client.on('ready',()=>{
    console.log('ftp client is ready');
});
client.on('close',()=>{
    console.log('ftp client has close')
});
client.on('end',()=>{
    console.log('ftp client has end')
});
client.on('error',(err)=>{
    console.log('ftp client has an error : '+ JSON.stringify(err))
});
client.connect({
    host : '***',//这个就不提供啦
    port : '***',
    user : '***',
    password : '***',
    keepalive : 1000
});
//列出目标目录
async function list(dirpath){
    let {err : ea,dir } = await cwd(dirpath);
    return new Promise((resolve,reject)=>{
        client.list((err,files)=>{
            resolve({err : err,files : files})
        })
    });
}
//切换目录
function cwd(dirpath){
    return new Promise((resolve,reject)=>{
        client.cwd(dirpath,(err,dir)=>{
            resolve({err : err,dir : dir});
        })
    });
}
//下载文件
async function get(filePath){
    const dirpath = path.dirname(filePath);
    const fileName = path.basename(filePath);
    let {err : ea,dir} = await cwd(dirpath);
    return new Promise((resolve,reject)=>{
        client.get(fileName,(err,rs)=>{
            let ws = fs.createWriteStream(fileName);
            rs.pipe(ws);
            resolve({err : err});
        });
    });
}
//将文件上传到ftp目标地址
async function put(currentFile,targetFilePath){
    const dirpath = path.dirname(targetFilePath);
    const fileName = path.basename(targetFilePath);
    const rs = fs.createReadStream(currentFile);
    let {err : ea,dir} = await cwd(dirpath);//此处应对err做处理
    if(ea){
        return Promise.resolve({err : ea});
    }
    return new Promise((resolve,reject)=>{
        client.put(rs,fileName,(err)=>{
            resolve({err : err});
        })
    });
}
async function test (){
    //list 列表功能
    let {err,files} = await list('/attachment/byycampus/resource');
    if(err){
        console.log(err);
        return
    }
    console.log(`获得文件列表:`+files.length);
    console.log(files);
    //下载文件
    let {err : ea} = await get('/attachment/byycampus/resource/201812/14/201812141035222541381967.jpg');
    if(ea){
        console.log(ea);
        return;
    }
    console.log('文件下载成功')
    //文件上传
    let {err : eb} = await put('201812141035222541381967.jpg','/attachment/a.jpg');
    if(eb){
        console.log(eb);
        return;
    }
    console.log('文件上传成功')
}
test();

踩坑记录:

笔者测试过程中发现,有的ftp服务器传输速度正常,而有的ftp服务器传输速度则是非常慢!慢到平均一张十几K的图片都能传十几秒的程度!经过检查发现,这类ftp是采用的被动连接模式。

对此,查找github官方文档https://github.com/mscdex/node-ftp , 发现connect函数中有一个pasvTimeout选项涉及到被动连接超时设置,于是笔者测试了一下,将上面的连接代码改成如下:

const ftp = require('ftp');//连接FTP
const client = new ftp();
client.on('ready',()=>{
    console.log('ftp client is ready');
});
client.connect({
    host : '***.***.***.***',
    port : '****',
    user : '***',
    password : '***',
    keepalive : 1000,
    pasvTimeout:1000
});

再次测试,传输速度慢的问题得到解决!

(0)

相关推荐

  • Node.js实现批量下载图片简单操作示例

    本文实例讲述了Node.js实现批量下载图片简单操作.分享给大家供大家参考,具体如下: 使用Node.js批量下载图片 首先要获取到图片链接: const img = [ "http://yw-yx.oss-cn-hangzhou.aliyuncs.com/ywwl-jylesson/2019/08/52218400506629423.jpg", "http://yw-yx.oss-cn-hangzhou.aliyuncs.com/ywwl-jylesson/2019/08/

  • Node.js实现下载文件的两种实用方式

    目录 第一种方式:使用原生的http模块 第二种方式:使用Express+Axios下载文件 总结 设置响应头 返回数据流 第一种方式:使用原生的http模块 我们仅需要用到fs和http两个node.js的原生模块,不需要安装第三方模块,就可以实现文件的下载.代码如下: var fs = require('fs'); var http = require("http"); var server = http.createServer(); server.on("reques

  • Nginx服务器下防盗链的方法介绍

    修改 /usr/local/nginx/conf/nginx.conf 这个配置文件. 找到 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; }[/code] 修改成: location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { valid_referers none blocked *.jannn.com jannn.com; if($invalid_referer) { rewrite ^/ h

  • nodejs实现生成文件并在前端下载

    目录 nodejs生成文件并在前端下载 前端 后端 nodejs下载文件问题 第一种方式:使用原生的http模块 第二种方式:使用Express+Axios下载文件 总结 nodejs生成文件并在前端下载 最近遇到一个小需求,前端要下载一个json文件,内容是对应数据的json对象. 看网上写的都太复杂了,只是下载一个小文件,只需要用到res.end()就够了. 前端 在a标签上加上download属性就可以点击下载文件了,download可以赋值,值为下载之后的文件名.也可以留空,用原有的文件

  • node+axios实现下载外网文件到本地

    目录 引言 初始化项目 安装axios 实现逻辑 执行 引言 作为一个web前端开发,对axios肯定不陌生,但是在前端开发中,一般是使用axios来请求后端接口,获取数据.而使用node+axios下载网络文件到本地磁盘可能很少接触,搜索了很多相关的博客文章,讲解的好像都不够清晰明了,所以本文就记录一下实践方法. 初始化项目 npm init -y 安装axios npm i -S axios 实现逻辑 根目录下新建app.js // app.js const axios = require(

  • Nginx图片防盗链配置实例

    做运维的朋友经常会有一些烦恼,比如网站总是被人抄袭,比如网站总是被人引用上面的图片,虽然一张图两张图,并不耗费很多流量,但一旦引用的人多了,这个还是比较废流量的. 防盗链就是禁止其他网站引用自己网站资源而做的一系列设置,优点就不需要说了,绝多数就是防止资源浪费,特别是有宽带.流量限制的空间如果不做一些 限制可能就光引用自己网站图片.视频等等资源可能会消耗很大一部分流量.本文就简单的说一下在nginx服务器上如何做防盗链设置. nginx防盗链代码 第1步:下载nginx网站配置文件. 有些网友可

  • 配置Nginx的防盗链的操作方法

    实验环境 •一台最小化安装的CentOS 7.3虚拟机 •配置:1核心/512MB •nginx版本1.12.2 一.配置盗链网站 1.启动一台nginx虚拟机,配置两个网站 vim /etc/nginx/conf.d/vhosts.conf 添加以下内容 server { listen 80; server_name site1.test.com; root /var/wwwroot/site1; index index.html; location / { } } server { list

  • Nginx防盗链的配置方法

    处于服务性能的考虑,我们通常把HTML静态资源按照不同类型划分存放在多台服务上. 如果拓扑图: 超文本传输协议中的Referer作用 Referer:null    表示请求者直接访问 Referer:blocked  一般为防火墙设备添加的 Referer:URL      表示URL中的主机告诉请求者的间接访问 图中jpg.good.com显然是一台专门用户存放图片的服务器,而www.good.com是一台WEB服务器,从域名可以看出必然是一家公司,条件: 1.只允许访问www.good.c

  • nginx配置防盗链的三种实现方式总结

    目录 什么是资源盗链 一.引导案例 二.Nginx防盗链实现原理 三.Nginx防盗链具体实现 实现方式一 实现方式二 实现方式三 总结 什么是资源盗链 资源盗链是指内容不在自己服务器上,而通过技术手段,绕过别人的限制,将别人的内容,比如热门的图片放到自己页面上,展示给用户,以此来盗取别人网站的流量,即蹭流量. 简而言之就是用别人的东西成就自己的网站 如下,分别在网上找的两个图片,可以直接在浏览器中打开这2个链接 一.引导案例 接下来,利用上面的这两个图片链接,我们在nginx的资源目录下,创建

  • node.js突破nginx防盗链机制,下载图片案例分析 原创

    问题 今天项目需求要求采集几个网站的信息,包括一些区块链统计图表之类的信息. 笔者使用的是node.js+axios库发送get请求来获取在图片,下载到本地.测试代码如下: import fs from 'fs'; import path from 'path'; import http from 'http'; import https from 'https'; const __dirname = path.resolve(); let filePath = path.join(__dirn

  • nginx利用referer指令实现防盗链配置

    实现图片防盗链: location ~* \.(gif|jpg|png|webp)$ { valid_referers none blocked domain.com *.domain.com server_names ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; #rewrite ^/ http://www.domain.com/403.jpg; } root /opt/www/image; } 以上所有来至domain

随机推荐