在局域网内互传纯文本和文件的云剪贴板
即开即用的网页版,无须安装 APP
参考了TransparentLC的cloud-clipboard项目
由于这个项目是针对个人在连接到同一局域网(比如家里的路由器)的设备之间使用而设计的,因此并没有额外考虑在公开的服务器上使用时可能面对的技术和安全问题。
前端:Ant Design Vue + Vite + Vue3;
后端:koa
适配:主要使用flex布局
解压后,双击easychuan.exe
,即可启动,访问ip + 9501,如 http://192.168.0.100:9501/#/
目录结构
| config.json 配置文件
| easychuan.exe
| history.json 历史记录
| package.json
|
+---build
+---static
\---vendor
C:\Users\ADMINI~1\AppData\Local\Temp\.cloud-clipboard-storage
{ "server": { // 监听的 IP 地址,省略或设为null则会监听所有网卡的IP地址 "host": [], "port": 9501, // 端口号 "key": null, // HTTPS 私钥路径 "cert": null, // HTTPS 证书路径 "history": 10, // 消息历史记录的数量 "auth": false // 是否在连接时要求使用密码认证,falsy 值表示不使用 }, "text": { "limit": 20000, // 文本的长度限制,最大支持2万个字符 }, "file": { "expire": 86400, // 24小时有效期,上传文件的有效期,超过有效期后自动删除,单位为秒,60*60*24 "chunk": 2097152, // 上传文件的分片大小,不能超过 2 MB,单位为 byte,1024*1024*2 "limit": 268435456, // 上传文件的大小限制,不能超过 256 MBMB,单位为 byte,1024*1024*256 } }
npm install -g nexe
nexe -i index.js -o dist/easychuan.exe -t x64-14.15.3
其中-i指定输入,-o指定输出,-t指定目标。
参考:vue3中在<script setup>中获取全局内容(三种方式)
新建.env.development
, 设置VITE_API_HOST='/api'
。
配置文件web_vite_vue3\vite.config.js
import Components from "unplugin-vue-components/vite"; import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"; import viteCompression from "vite-plugin-compression"; ... // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), Components({ resolvers: [ AntDesignVueResolver({ importStyle: false, // css in js resolveIcons: true, // 自动按需引入图标 }), ], }), viteCompression({ filename: "[path][base].gz", algorithm: "gzip", test: /.js$|.css$|.html$/, threshold: 10240, // 对超过10k的数据压缩 minRatio: 0.8, // 压缩率小于0.8才会压缩 }), ], ... server: { port: 3001, host: "0.0.0.0", hmr: true, proxy: { "/api": { target: "http://localhost:9501", ws: false, // 这里把ws代理给关闭 changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), }, "/file": { target: "http://localhost:9501", ws: false, // 这里把ws代理给关闭 changeOrigin: true, }, }, }, build: { rollupOptions: { output: { chunkFileNames: "js/[name]-[hash].js", // 引入文件名的名称 entryFileNames: "js/[name]-[hash].js", // 包的入口文件名称 assetFileNames: "[ext]/[name]-[hash].[ext]", // 资源文件像 字体,图片等 }, }, }, });
电脑上页面传输可以,但是手机上连不上,因为请求 '/server',返回的是ws://localhost:9501/push
而手机上无法请求localhost
//获取本机ip地址 function getIPAdress() { let interfaces = os.networkInterfaces(); for (let devName in interfaces) { let iface = interfaces[devName]; for (let i = 0; i < iface.length; i++) { let alias = iface[i]; if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { return alias.address; } } } } const ip = getIPAdress(); router.get('/server', async ctx => { ctx.body = { // server: `ws://${ctx.request.host}/push`, server: `ws://${ip}:${config.server.port}/push`, auth: !!config.server.auth, }; });