node.js实现复制文本到剪切板的功能


Posted in Javascript onJanuary 23, 2017

前言

最近在工作中遇到一种需求:我需要请求后端数据,但请求数据前需要登陆,获得一个token。登陆方式是向一个json地址post数据即可。之前我的做法是,用chrome插件postman来实现登陆动作。但后来无意中发现,postman内存占用超高!即使我并没有使用它。这让我很不爽。

后来一想,实现这么简单的一个动作,用这么重的插件,对于我这样一个会nodejs的前端程序员是不是太Low了?简直不好意思对人讲自己会nodejs!

于是我就花了点时间写了个简单的脚本。本文记录一下开发过程。

实现思路

思路大概是,用nodejs脚本发请求,并将返回结果中的token自动复制到剪切板,于是我只用在调试代码中,ctrl+v就行了。

思路很简单,但实现起来居然坑很多。

nodejs没有直接复制到剪切板的API!

非常简单的功能,但nodejs没有提供。但不要绝望,因为nodejs可以调用系统命令,而系统命令中有不少可以操作剪切板的命令。

我google之后,由于系统是windows,所以考虑使用windows cmd命令中的clip,来实现复制到剪切板的功能。

nodejs调用系统命令(cmd)

var exec = require(‘child_process').exec,然后你就可以像普通函数一样调用它,如:exec(‘echo 111');

clip命令的坑

在cmd里,实现复制文本到剪切板最简单的命令是:echo 123456 | clip。本来,在nodejs中拼出这样一句语句,交给child_process.exec执行就可以了。但这个命令的执行结果,有个我无法忍受的bug:复制出来的文本,最后有个换行符(echo造成的)!我不可能在ctrl+v后,还要按几下删除键才能ctrl+s啊!

当时让我很纠结,我很奇怪微软连这么简单的命令都没作好。但无奈事情还是要做的,只有继续寻找解决办法。于是有了下面这个不经过echo的方式:

<nul (set/p z=123456) | clip

这种方法十分别扭,注意最开头那个<,不是我打错了字!大致思路是,通过set命令设置一个变量名为p(此名随意改)的变量,值为12346,并马上调用clip复制此变量的值。 但这种方法复制出来的值还是有bug:末尾多了一个空格!虽然你代码里并没有空格,但复制出来就是有!去不掉! 当时我简直要骂娘了!没有换行就有空格,能不能靠点谱!

麻烦而稳妥的最终实现

最后我尝试了一种思路:得到要复制的文本后,生成一个临时文件,将文本放进去;生成一个批处理文件,在批处理文件中调用clip命令,复制那个文本文件的内容;最后删除临时文本文件与批处理文件。

当时我想的是,要是这种方式还不能完美,我就弃nodejs投python!

所幸复制出来的文本,终于正常了,没有换行符,没有空格。

代码如下,为了方便发请求使用了request包:

'use strict';

var request = require('request');
var fs = require('fs');

var exec = require('child_process').exec;
var execFile = require('child_process').execFile;
request({
 method: 'POST',
 uri:'http://web.test1.com/mgw/login.json',
 headers: {
  'Content-Type':'application/json'
 },
 body: JSON.stringify({
  "loginname":"lixing1@0101005",
  "pw":"aebc3ebee2f0c8b08b43d26c2b0055b19caeaf4a",
  "res":"web"
 })
 }, function (err, result, body) {
 console.log(body);
 body = JSON.parse(body);
 copyToClipboard(body.token, function (text, stdout) {
  console.log('token copy successed!', text, stdout);
 })
});


// 简单的复制文本到剪切板的函数,参数依次是文本,成功回调
var copyToClipboard = function(text, func) {
 // 这种复制出来后最后有个换行符,不合要求
 'echo ' + text + ' | clip';
 // 这种复制出来最后有个空格,还将就
 '<nul (set/p z=' + text + ') | clip';

 // 这种方式最完美,但最麻烦
 // 会生成一个批处理文件,一个文本文件,以批处理文件复制文件文件的内容,后又需要删除两个文件。
 var temp = 'txt_' + Date.now() + '.txt';

 var str = `@echo off
<nul (set/p z=${text}) > ${temp} 
clip < ${temp} 
del ${temp}
`;
// 这句加入批处理,会导致报错,虽然能执行(复制)成功。原因应该是,del批处理文件自身的时候,nodejs还在使用他
// 'del "%~f0"';
 var cmdFile = 'ttzkxlcjv.cmd';
 fs.writeFile(cmdFile, str);
 exec(cmdFile, function(err, stdout, stderr) {
 if (err || stderr) return console.log(err, stdout, stderr);
 // 用nodejs删除文件
 fs.unlink(cmdFile);
 func(text, stdout);
 });
};

这里面涉及到cmd clip的另一个用法,即 clip < a_text.txt,这样会将后面这个文件的内容,复制出来。 这里面还有个小坑。即在批处理文件中,加入del "%~f0"删除自身,本来是可以用的,但在nodejs里执行却会报错,后来我猜想,应该是因为批处理文件在执行到删除自身的命令时,进程还被nodejs引用着,结果报错了。后来只有调用nodejs的fs.unlink命令,删除那个批处理文件。

总结

通过实现这个功能,我学会了使用Request包,调用系统命令,clip的使用方法。果然实实在在的需求,才是最强的生产力。

要是linux或mac系统,实现此功能就简单多了。

clip命令不只可以复制文本,大家可以探索下。

备: 最近嫌每次都要自己ctrl+v太麻烦,所以我使用fs.readFile与fs.writeFile,将请求回来的token直接写入我的配置文件。以上的剪切板功能也就没用上了,不过我觉得很适合记录下来这次经历。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
jquery序列化form表单使用ajax提交后处理返回的json数据
Mar 03 Javascript
js无刷新操作table的行和列
Mar 27 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
JS中字符串trim()使用示例
May 26 Javascript
JS实现霓虹灯文字效果的方法
Aug 06 Javascript
纯JS实现可拖拽表单的简单实例
Sep 02 Javascript
微信小程序 wx.request(object) API详解及实例代码
Sep 30 Javascript
js原生之焦点图转换加定时器实例
Dec 12 Javascript
Jquery实时监听input value的实例
Jan 26 Javascript
在element-ui的el-tree组件中用render函数生成el-button的实例代码
Nov 05 Javascript
原生JS生成指定位数的验证码
Oct 28 Javascript
jQuery实现影院选座订座效果
Apr 13 jQuery
jQuery 全选 全不选 事件绑定的实现代码
Jan 23 #Javascript
Javascript中构造函数要注意的一些坑
Jan 23 #Javascript
在 Angular2 中实现自定义校验指令(确认密码)的方法
Jan 23 #Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
Jan 23 #Javascript
利用JS实现简单的日期选择插件
Jan 23 #Javascript
获取IE浏览器Cookie信息的方法
Jan 23 #Javascript
jQuery实现的简单悬浮层功能完整实例
Jan 23 #Javascript
You might like
PHP通过内置函数memory_get_usage()获取内存使用情况
2014/11/20 PHP
php删除数组中重复元素的方法
2015/12/22 PHP
CI框架封装的常用图像处理方法(缩略图,水印,旋转,上传等)
2016/11/22 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
PHP进阶学习之Geo的地图定位算法详解
2019/06/19 PHP
laravel admin实现分类树/模型树的示例代码
2020/06/10 PHP
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
基于html5和nodejs相结合实现websocket即使通讯
2015/11/19 NodeJs
node网页分段渲染详解
2016/09/05 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
纯JS实现图片验证码功能并兼容IE6-8(推荐)
2017/04/19 Javascript
微信小程序使用audio组件播放音乐功能示例【附源码下载】
2017/12/08 Javascript
微信小程序中换行空格(多个空格)写法详解
2018/07/10 Javascript
vue 中引用gojs绘制E-R图的方法示例
2018/08/24 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
2019/12/04 Javascript
[04:19]完美世界携手游戏风云打造 卡尔工作室模型介绍篇
2013/04/24 DOTA
python list 合并连接字符串的方法
2013/03/09 Python
python统计文本文件内单词数量的方法
2015/05/30 Python
PyQt5每天必学之弹出消息框
2018/04/19 Python
python将print输出的信息保留到日志文件中
2019/09/27 Python
Python3列表List入门知识附实例
2020/02/09 Python
美国杰西潘尼官网:JCPenney
2019/06/12 全球购物
欧姆龙医疗保健与医疗产品:Omron Healthcare
2020/02/10 全球购物
公司董事长职责
2013/12/12 职场文书
国际贸易毕业生求职信
2014/07/20 职场文书
公司法人授权委托书范本
2014/09/12 职场文书
对照四风自我剖析材料
2014/10/07 职场文书
党的群众路线教育实践活动整改落实情况报告
2014/10/28 职场文书
2014年质检工作总结
2014/11/26 职场文书
离婚代理词范文
2015/05/23 职场文书
golang如何去除多余空白字符(含制表符)
2021/04/25 Golang
解决Navicat for Mysql连接报错1251的问题(连接失败)
2021/05/27 MySQL
Python制作一个随机抽奖小工具的实现
2021/07/07 Python