<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Rzsz | 进击之路 - Alan的个人博客</title><link>https://1991421.cn/tag/rzsz/</link><atom:link href="https://1991421.cn/tag/rzsz/index.xml" rel="self" type="application/rss+xml"/><description>Rzsz</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>zh-CN</language><lastBuildDate>Tue, 17 May 2022 22:57:20 +0800</lastBuildDate><image><url>https://1991421.cn/media/sharing.png</url><title>Rzsz</title><link>https://1991421.cn/tag/rzsz/</link></image><item><title>WebShell中实现sz/rz上传下载</title><link>https://1991421.cn/2022/05/17/webshellsz-rz/</link><pubDate>Tue, 17 May 2022 22:57:20 +0800</pubDate><guid>https://1991421.cn/2022/05/17/webshellsz-rz/</guid><description>&lt;blockquote>
&lt;p>最近支持上传下载，做了&lt;code>lrzsz&lt;/code>的调研开发，这里总结下&lt;/p>
&lt;/blockquote>
&lt;h2 id="使用说明">
&lt;a class="heading-anchor-link" href="#%e4%bd%bf%e7%94%a8%e8%af%b4%e6%98%8e">使用说明&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="使用说明"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>首先了解下rzsz功能&lt;/p>
&lt;ol>
&lt;li>
&lt;p>sz支持&lt;code>多文件下载&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>rz支持&lt;code>多文件上传&lt;/code>，上传目标目录为当前命中执行目录，&lt;/p>
&lt;/li>
&lt;li>
&lt;p>rz&lt;code>不支持文件夹上传&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>rz上传针对已存在文件，会有标记信息说明&lt;/p>
&lt;/li>
&lt;li>
&lt;p>针对体积大小，无法传输大于 &lt;code>4G&lt;/code> 的文件&lt;/p>
&lt;/li>
&lt;li>
&lt;p>下载中/上传中&lt;code>支持取消&lt;/code>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="rzsz系统支持">
&lt;a class="heading-anchor-link" href="#rzsz%e7%b3%bb%e7%bb%9f%e6%94%af%e6%8c%81">rzsz系统支持&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="rzsz系统支持"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>服务器默认是没有安装 &lt;em>lrzsz&lt;/em> 工具的，需要手动安装&lt;/li>
&lt;li>不是所有工具都支持 rz 与 sz，必须支持 &lt;code>ZModem&lt;/code> 协议才行，安装脚本如下&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># MacOS&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew install lrzsz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew remove lrzsz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># CentOS&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum install lrzsz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum remove lrzsz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">## 跨平台安装脚本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo sh -c &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>curl -fsSL https://gist.githubusercontent.com/alanhe421/6a299b815f4dd3d242abc16b8be6b861/raw/dbe1497208f1d968ed8b67cad09c596e35c5be9c/install-package-lrzsz.sh&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="官方demo">
&lt;a class="heading-anchor-link" href="#%e5%ae%98%e6%96%b9demo">官方demo&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="官方demo"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;blockquote>
&lt;p>zmodem.js作者提供了demo，方便了解。为了保证demo正常运行，需要以下操作&lt;/p>
&lt;/blockquote>
&lt;ol>
&lt;li>demo地址：https://github.com/FGasper/xterm.js/tree/zmodem&lt;/li>
&lt;li>node版本切换到&lt;code>v8&lt;/code>重新执行&lt;code>npm i&lt;/code>&lt;/li>
&lt;li>启动后访问http://127.0.0.1:3000/&lt;/li>
&lt;/ol>
&lt;h2 id="功能实现">
&lt;a class="heading-anchor-link" href="#%e5%8a%9f%e8%83%bd%e5%ae%9e%e7%8e%b0">功能实现&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="功能实现"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>上述作者的demo比较简单，并未提及一些功能，这里贴下关键实现。完整例子&lt;a href="https://github.com/alanhe421/express-demo" target="_blank" rel="noopener">戳这里&lt;/a>&lt;/p>
&lt;h2 id="sz取消下载">
&lt;a class="heading-anchor-link" href="#sz%e5%8f%96%e6%b6%88%e4%b8%8b%e8%bd%bd">sz取消下载&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="sz取消下载"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>上传直接唤起的资源管理器选择框，在取消后，JS层面无法得知，因此只能用户主观再按&lt;code>ctrl c&lt;/code>取消，之后发送abort命令进行取消。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">activeZsession&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">_skip&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>除了上述方法外，还有个办法就是自行增加上传弹窗，让用户点击时再调用abort即可。&lt;/p>
&lt;h2 id="rz取消上传">
&lt;a class="heading-anchor-link" href="#rz%e5%8f%96%e6%b6%88%e4%b8%8a%e4%bc%a0">rz取消上传&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="rz取消上传"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 停止发送数据块，xfer.send(chunk)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">await&lt;/span> &lt;span class="nx">zsession&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">close&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="上传-文件已存在">
&lt;a class="heading-anchor-link" href="#%e4%b8%8a%e4%bc%a0-%e6%96%87%e4%bb%b6%e5%b7%b2%e5%ad%98%e5%9c%a8">上传-文件已存在&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="上传-文件已存在"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;p>xfer识别为空即表示服务端拒绝上传，目前发现原因是文件存在，不排除有其它可能性。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">xfer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="nx">zsession&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">send_offer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">curb&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">xfer&lt;/span>&lt;span class="p">){&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">showMessage&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">xfer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get_details&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb"> rejected.`&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="进度打印">
&lt;a class="heading-anchor-link" href="#%e8%bf%9b%e5%ba%a6%e6%89%93%e5%8d%b0">进度打印&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="进度打印"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>针对上传，根据已发送大小/总大小计算进度，针对下载则是接收的大小/总大小。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>上传进度，循环直接打印进度会不work，原因是xterm并非同步打印，为了解决该问题，增加delay即可。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">await&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Promise&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">resolve&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nb">window&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setTimeout&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">resolve&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>考虑到体验，可以除了进度之外显示下进度条, xterm.write时候不要\n换行显示即可。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">getProgressBar&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">total&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">current&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">total&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="nx">current&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nb">Error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;total must be greater than current&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">progressBarLength&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">40&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// 进度条的长度
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">progress&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">Math&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">floor&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">current&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="nx">total&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">progressBarLength&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">empty&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">progressBarLength&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="nx">progress&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">progressBar&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;█&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">repeat&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">progress&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39;░&amp;#39;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">repeat&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">empty&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="sb">`(&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">progressBar&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">) &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">current&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="nx">total&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">100&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">toFixed&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">%`&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="有价值的资料">
&lt;a class="heading-anchor-link" href="#%e6%9c%89%e4%bb%b7%e5%80%bc%e7%9a%84%e8%b5%84%e6%96%99">有价值的资料&lt;/a>
&lt;button
class="heading-anchor"
type="button"
data-anchor="有价值的资料"
aria-label="复制锚点链接"
title="复制锚点链接"
>
&lt;span class="heading-anchor-wrap" aria-hidden="true">
&lt;svg class="heading-anchor-icon heading-anchor-icon-default" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" fill="currentColor">
&lt;path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z">&lt;/path>
&lt;/svg>
&lt;svg class="heading-anchor-icon heading-anchor-icon-copied" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
&lt;path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm107.1 145.1L230.6 325.6c-6.2 6.2-16.4 6.2-22.6 0l-59-59c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l47.7 47.7 121.1-121.1c6.2-6.2 16.4-6.2 22.6 0s6.3 16.4.1 22.5z">&lt;/path>
&lt;/svg>
&lt;/span>
&lt;/button>
&lt;/h2>&lt;ol>
&lt;li>&lt;a href="https://juejin.cn/post/6935621453400244260" target="_blank" rel="noopener">https://juejin.cn/post/6935621453400244260&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://wsgzao.github.io/post/lrzsz/" target="_blank" rel="noopener">https://wsgzao.github.io/post/lrzsz/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://qa.1r1g.com/sf/ask/672770031/" target="_blank" rel="noopener">https://qa.1r1g.com/sf/ask/672770031/&lt;/a>&lt;/li>
&lt;/ol></description></item></channel></rss>