基于什么目的我会手动开发一个 FTP 客户端呢?其实,很简单,爱折腾,若是不是喜欢折腾,可能就不会对软件开发如此痴迷,对其中的实现原理如此痴迷,一个不喜欢折腾的程序员,可能会失去方向感。最近公司集成第三方厂商的业务愈来愈多,SDK 也愈来愈大,SVN 服务器不容许对超过 50 MB以上的 SDK 进行管理,那咱们将这些 SDK 放哪儿呢?没错,就是 FTP 服务器,过去的半年我做为 Mac 的用户使用 FTP 体验极其糟糕,系统的 Finder 访问 FTP 服务器没法访问,线上的软件也没找到合适的,半年下来我捣鼓了虚拟机,装了 Window10 ,在 Mac 和 Window10 之间,常年处于无缝切换的状态。html
事实上,出于对原理的好奇,决定动手开发 FTP 客户端,开发过程总共 20 小时,大约 4 个晚上,中间也遇到过问题,也一并解决,整个儿过程下来,收获颇丰。vue
客户端下载地址 blogzzyc.obs.cn-east-2.myhuaweicloud.com/ipa/ftpclie…node
FTP 业务的核心,必定是与服务器的链接,在 gihtub 上找到了一个 4 年前的产物“node-ftp”。程序员
总体文档上看下来,功能齐全,手动测试了下,能够正常访问 FTP 服务器,因而就决定使用该模块。(这里有一个小问题,我没有全面测试 API,只测了一个链接的 API,致使在后续开发过程当中使用 API 的时候 产生中文编码问题,这里体现了技术调研,必定要严谨,仔细)web
客户端容器使用 nwjs(node-webkit),实际上我对这个技术关注已久,一直没有机会可以动手实践一下,这回终于让我用上了,nwjs 其实是一个 Hybrid App,你能够直接在容器中使用 nodejs 的 API 做为 Native Code,仍是很爽的。vue-cli
表现层,我则使用了 Vue+ElmemtUI,当下最火,开发效率高,非他们莫属。npm
废话不说,直接上手干,在网上找了一款现成的 Vue+ElementUI 后台项目模版,一顿 npm instal
、npm run serve
,将项目运行出来,迅速将模版中不须要的模块删除,一番操做后,就遇到了第一个问题,Vue 的工程里不能直接用 nodejs?使用 npm run serve
启动了本地的开发服务,哦!?,须要将地址跑在 nwjs 里才行吧,因而前往 nwjs.io 的官网,看了下文档后,开启了 remote-debug
模式,而后把地址放在调试模式的容器中跑起来,这下应该成功了吧?,一运行,仍是报红,后来我仔细想了下,Webpack 有一个编译过程,若是在 Vue 的工程中直接写 nodejs 的代码,可能会被编译 es5 其余的语法,机智如我,因而我在 public 目录下新增 NWBridge.js 文件,在 index.html 主动引入文件,该文件负责链接 Vue 的事件和 nodejs 的 API,再次运行,再次用 remote-debug
运行,仍是不行,理论上此次应该是成功的,可是并无,我又想了下,是否是 nwjs 不容许在线地址调用 nodejs,我打开 nwjs 的 DevTool,输入了 location.href=开发地址
,此次直接跑起来,可是 nodejs 的 API 依旧没有调用成功,只剩下最后依照,只能打成 nwjs 本地调试包,利用命令执行,接下来就是使用npm run build
,而后增长 package.json 文件,新增一个 nwjs 的开发目录 nw,将生成的源码包和 package.json 文件放进去,而后利用全局命令nwjs ./nw
,这一次运行成功,nodejs API 也调用成功了,内心大喜,可是一想,每次修改东西都须要干这件事情,太复杂,能不能将这件事情自动化,因而我就修改了 npm run build
命令,变成了以下 (vue-cli-service build)&&(rm -rf ./nw/dist)&&(mv dist ./nw)&&(nwjs ./nw)
一顿操做,搞定,这样每次修改完后,只须要执行npm run build
就能够预览、调试了,到此,开发环境算是搭建好了。json
页面的怎么开发的,就不说了,工做量也很少无非就那么几下,接下来准备对接第一个 API ,显示目标服务器的目录,一顿捣鼓后,就有了以下效果:服务器
很开心,因而对接各个模块的点击,进入子目录,这时候遇到了严重的问题,中文目录没法访问,点击无效果,这个问题我花的时间最长,解决花了 6 个小时,这里要注意咱们一开始是拿不到中文目录的,如今能看到中文是由于我使用了iconv-lite
模块,对其进行 GBK 转 UTF-8 编码,因此能够看到中文目录,FTP 的服务器必定是个 Window 服务器,由于 GBK 只有 Window 才有,而 nodejs 中不支持 GBK,因此须要这个著名的库iconv-lite
。到目前为止,表现层可能没法解决这个问题了,因而我将内容最小化,利用 js 脚本直接执行中文命令,我发现不行,并不能访问,因此不得不读 node-ftp 的源码,源码比较少,我花了两个小时就看完了,我发现其原理和 smtp、iamp 相似,一样是架起 socket 链接指定服务器,而后向管道里写入 FTP 标准的指令,例如LIST
命令,到这里我忽然理解,管道写过来的是 GBK,写回去的必定也是 GBK 才行,因而修改源代码,将管道统一写回的地方,利用 iconv-lite
进行一层转换,可发现仍是不行,因而我就取回管道过来的中文字节,对其中的中文字节手动筛选,找到指定文件名的中文变量,将字节原封不动的从管道写回去,这一次,成功了!!,这证实理论没错,因而我再次对写死的中文,经过一层转换写回管道,可仍是不行,此次又是为何呢?无奈,再次排查后,发现我直接用写死的‘中文字符串’,转换出来的字节和从FTP管道写回来的中文参数转换出来的字节,差了一位,就由于一位致使没法执行命令,因而这一次,我直接用FTP管道写回的中文变量,再次访问其子目录,果真这一次成功了。socket
放一张成功的图,成功进入其余
子目录。
上述问题解决后,基本没有大问题了,因而开始开发剩下的内容,其中包括上传文件
、下载文件
、删除文件
、新增文件夹
、导航栏面包屑
、FTP记录读写
等,这其中下载文件遇到一个问题,文件保存对话框如何打开,由于 <input type='file' />
标签只负责选择上传文件操做,到这里我想到 nwjs 容器应该会提供对应的方法,因而又再次前往 nwjs.io 官网阅读文档,果真让我找到了以下内容:
果真 nwjs 对 input 标签进行重载,让他支持了文件另存为,OK!!到此功能所有完成,最后开始打包咱们的 App。
为何我须要去作这件事情,由于有计划就须要付诸实践,不然想法只能留在脑海里,nwjs 就留了好久,而作完这件事情后,我又发现本身对 Hybrid App 的理解更加深入,做为程序员,主动性驱动很重要,必定要主动的发现需求,发现问题,主动的去沟通,去交互,程序员之间无非就是比谁先踏出本身的一亩三分地,谁先主动行动,谁才能收获更多。