群晖部署局域网跨设备传输神器Snapdrop并手动汉化

简介

Snapdrop是一款WEB工具,实现了非常方便的跨设备文件传输,其灵感来源于苹果的Airdrop。在同一个局域网内的设备,只要打开同一个网址即可互发消息、传送文件。

其官方提供的服务为:https://snapdrop.net/,当然作为一个开源服务,Snapdrop也支持通过Docker自行部署,下面为大家带来,在群晖的Docker中部署Snapdrop的教程,并附上汉化方法。

安装部署

前置条件

群晖已经安装Docker套件,如果没有,则需要打开群晖套件中心安装Docker

使用群晖的任务计划部署Snapdrop

部署语句:

docker run -d -p 8080:80 linuxserver/snapdrop

部署过程(看起来很复杂,实际很简单):

  1. 打开 控制面板 -> 任务计划
  2. 新增 -> 计划的任务 -> 用户自定义的脚本
  3. 常规选项卡:
    1. 设定任务名称:随意设置只能是英文,默认也行
    2. 用户账号:选择 root
    3. 已启用:取消勾选(不取消也行,后面可以设置一个已过期的日期)
  4. 计划选项卡:
    1. 选择在以下日期运行
    2. 随意设定一个可用日期,最好是已经过去的日期
  5. 任务设置选项卡:
    1. 将修改好的语句粘贴到 用户自定义脚本输入框
    2. 确定
  6. 任务计划列表中,右键要执行的项目-> 运行,等待~~~
  7. 要具体查看执行结果:单击该项目-> 动作 -> 查看结果,一般来讲 正常(0) 表示运行完成。
  8. 这时就可以打开 群晖ip:8080进行访问了。
通过任务计划部署 Docker 容器

汉化Snapdrop

如果只是个人使用的话,经过之前的步骤,已经可以开始使用了,如果想更加方便,或者打算分享出去给大家使用,还是汉化一下比较好。

将Docker中的文件拷贝到本地

提示:这里的逻辑是将Snapdrop容器内的项目文件,拷贝到群晖的实体目录,然后修改文件。实际上也可以只将要修改的HTML文件拷贝出来,之后映射文件即可。法无定法都能实现目的。

从Docker中拷贝文件到本地的语句

docker cp 容器名:要拷贝的目录(Snapdrop需要的是/app) 自定义路径
-- 例如(注意空格):
docker cp relaxed_bouman:/app /volume1/docker/snapdrop
  1. 按照上面使用群晖任务计划部署的方法,执行以上语句。
  2. 完成后,即可在自定义的文件夹中找到拷贝出来的app文件夹
  3. 在app文件夹上点右键,设置拥有者为当前账户,并勾选应用到子文件

在Docker中建立目录映射

  1. 停止当前的容器
  2. 选中并点击编辑按钮
  3. 设置文件夹映射并保存

汉化页面

  1. 找到文件:/app/www/client/index.html ,此时最好备份一个
  2. 右键->用文本编辑器打开
  3. 注意:文件->编码->Unicode(UTF-8),否则保存后中文会乱码
  4. 修改自己想汉化的部分并保存

见文章最后,有我已经修改好的代码(包含显示页面二维码)

可以参考修改,也可以直接使用。或者根据下一步教程,自己制作一下

也可以删掉相关代码,不显示二维码等。

为页面增加一个二维码方便扫描打开

  1. 打开生成二维码的网站草料网址二维码生成器 (cli.im)
  2. 输入自己部署的URL,点击生成二维码
  3. 下载二维码命名为erweima.png,上传到/app/www/client/images
  4. 在/app/www/client/index.html 文件中插入如下代码:
<h2>Open Snapdrop on other devices to send files</h2> 
<!-- 将以下代码插入到上面这行代码之后 --> 
<!-- 加入网址和二维码的代码开始 --> 
        <h3 style="opacity: 0.5;">打开下面网址:<br><script>document.write(document.location.href)</script></h3>
        <h2>或扫二维码</h2>
        <img style="opacity: 0.7;" height="128" width="128" src="images/erweima.png">
        <h2>即可互传文件</h2>
<!-- 加入网址和二维码的代码结束 --> 

三个坑:

1小坑:Connection lost. Retry in 5 seconds…

这个问题出现在新版群晖7.xx中,使用了自带的反向代理的情况下。原因是群晖7.xx在设置反代的时候默认不支持ws协议。

解决方法如下:

  1. 打开设置好的反向代理规则
  2. 点自定义标题标签
  3. 点新增->WebSocket
  4. 点击保存

2小坑:无论是否在一个局域网都显示在画面上

这个问题同样出现在使用反向代理的情况下。因为在代理后面为节点服务器提供服务时,标头必须由代理设置。

一般的反向代理服务器的解决方法:

在反向代理的nginx/default.conf文件中,对应下面代码位置里加入高亮代码。

    location /server {
        proxy_connect_timeout 300;
        proxy_pass http://node:3000;
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Forwarded-for $remote_addr;
    }

群晖7.x的解决方法:

  1. 打开设置好的反向代理规则
  2. 点自定义标题标签
  3. 点新增->新增->标题名称:X-Forwarded-for->值:$remote_addr
  4. 点击保存

3大坑:iOS设备无法与其他设备传送文件问题

这个问题,目前官方的网站也会出现,而GitHub上也有很多反馈这个问题或者类似问题,也提出了千奇百怪的解决方法,但是没有一个解决掉我碰到的问题。只能希望官方后续的版本进行解决了。

当然页很有可能,你反而用起来没问题。无奈~~

汉化参考代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!-- Web App Config -->
    <title>Snapdrop</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="theme-color" content="#3367d6">
    <meta name="color-scheme" content="dark light">
    <meta name="apple-mobile-web-app-capable" content="no">
    <meta name="apple-mobile-web-app-title" content="Snapdrop">
    <!-- Descriptions -->
    <meta name="description" content="Instantly share images, videos, PDFs, and links with people nearby. Peer2Peer and Open Source. No Setup, No Signup.">
    <meta name="keywords" content="File, Transfer, Share, Peer2Peer">
    <meta name="author" content="RobinLinus">
    <meta property="og:title" content="Snapdrop">
    <meta property="og:type" content="article">
    <meta property="og:url" content="https://snapdrop.net/">
    <meta property="og:author" content="https://facebook.com/RobinLinus">
    <meta name="twitter:author" content="@RobinLinus">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:description" content="Instantly share images, videos, PDFs, and links with people nearby. Peer2Peer and Open Source. No Setup, No Signup.">
    <meta name="og:description" content="Instantly share images, videos, PDFs, and links with people nearby. Peer2Peer and Open Source. No Setup, No Signup.">
    <!-- Icons -->
    <link rel="icon" sizes="96x96" href="images/favicon-96x96.png">
    <link rel="shortcut icon" href="images/favicon-96x96.png">
    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
    <meta name="msapplication-TileImage" content="images/mstile-150x150.png">
    <link rel="fluid-icon" type="image/png" href="images/android-chrome-192x192.png">
    <meta name="twitter:image" content="https://snapdrop.net/images/twitter-stream.jpg">
    <meta property="og:image" content="https://snapdrop.net/images/twitter-stream.jpg">
    <!-- Resources -->
    <link rel="stylesheet" type="text/css" href="styles.css">
    <link rel="manifest" href="manifest.json">
</head>

<body translate="no">
    <header class="row-reverse">
        <a href="#about" class="icon-button" title="About Snapdrop">
            <svg class="icon">
                <use xlink:href="#info-outline" />
            </svg>
        </a>
        <a href="#" id="theme" class="icon-button" title="Switch Darkmode/Lightmode" >
            <svg class="icon">
                <use xlink:href="#icon-theme" />
            </svg>
        </a>
        <a href="#" id="notification" class="icon-button" title="Enable Notifications" hidden>
            <svg class="icon">
                <use xlink:href="#notifications" />
            </svg>
        </a>
        <a href="#" id="install" class="icon-button" title="Install Snapdrop" hidden>
            <svg class="icon">
                <use xlink:href="#homescreen" />
            </svg>
        </a>
    </header>
    <!-- Peers -->
    <x-peers class="center"></x-peers>
    <x-no-peers>
        <h2>在其他手机/电脑上也打开: </h2>
<!-- 加入网址和二维码的代码开始 --> 
        <h3 style="opacity: 0.5;">打开下面网址:<br><script>document.write(document.location.href)</script></h3>
        <h2>或扫二维码</h2>
        <img style="opacity: 0.7;" height="128" width="128" src="images/erweima.png">
        <h2>即可互传文件</h2>
<!-- 加入网址和二维码的代码结束 --> 
    </x-no-peers>
    <x-instructions desktop="点击发送文件,长按发送消息。" mobile="点击发送文件,长按发送消息。"></x-instructions>
    <!-- Footer -->
    <footer class="column">
        <svg class="icon logo">
            <use xlink:href="#wifi-tethering" />
        </svg>
        <div id="displayName">最简单的局域网内互传文件方案</div>
        <div class="font-body2"><br>声明:设备之间直接通过P2P互传文件,<br>服务器不会记录、保存、中转任何文件。</div>
    </footer>
    <!-- Receive Dialog -->
    <x-dialog id="receiveDialog">
        <x-background class="full center">
            <x-paper shadow="2">
                <h3>收到文件</h3>
                <div class="font-subheading" id="fileName">文件名</div>
                <div class="font-body2" id="fileSize"></div>
                <div class='preview' style="visibility: hidden;">
                    <img id='img-preview' src="">
                </div>
                <div class="row">
                    <label for="autoDownload" class="grow">Ask to save each file before downloading</label>
                    <input type="checkbox" id="autoDownload" checked="">
                </div>
                <div class="row-reverse">
                    <a class="button" close id="download" title="Download File" autofocus>下载</a>
                    <button class="button" close>忽略</button>
                </div>
            </x-paper>
        </x-background>
    </x-dialog>
    <!-- Send Text Dialog -->
    <x-dialog id="sendTextDialog">
        <form action="#">
            <x-background class="full center">
                <x-paper shadow="2">
                    <h3>发送消息</h3>
                    <div id="textInput" class="textarea" role="textbox" placeholder="发一条消息" autocomplete="off" autofocus contenteditable></div>
                    <div class="row-reverse">
                        <button class="button" type="submit" close>发送</button>
                        <a class="button" close>取消</a>
                    </div>
                </x-paper>
            </x-background>
        </form>
    </x-dialog>
    <!-- Receive Text Dialog -->
    <x-dialog id="receiveTextDialog">
        <x-background class="full center">
            <x-paper shadow="2">
                <h3>收到消息</h3>
                <div class="font-subheading" id="text"></div>
                <div class="row-reverse">
                    <button class="button" id="copy" close autofocus>复制</button>
                    <button class="button" close>关闭</button>
                </div>
            </x-paper>
        </x-background>
    </x-dialog>
    <!-- Toast -->
    <div class="toast-container full center">
        <x-toast class="row" shadow="1" id="toast">文件传输完成</x-toast>
    </div>
    <!-- About Page -->
    <x-about id="about" class="full center column">
        <section class="center column fade-in">
            <header class="row-reverse">
                <a href="#" class="close icon-button">
                    <svg class="icon">
                        <use xlink:href="#close" />
                    </svg>
                </a>
            </header>
            <svg class="icon logo">
                <use xlink:href="#wifi-tethering" />
            </svg>
            <h1>Snapdrop</h1>
            <div class="font-subheading">最简单的局域网内互传文件方案</div>
            <div class="row">
                <a class="icon-button" target="_blank" href="https://github.com/RobinLinus/snapdrop" title="Snapdrop on Github" rel="noreferrer">
                    <svg class="icon">
                        <use xlink:href="#github" />
                    </svg>
                </a>
                <a class="icon-button" target="_blank" href="https://www.paypal.com/donate?hosted_button_id=FTP9DXUR7LA7Q" title="Help cover the server costs!" rel="noreferrer">
                    <svg class="icon">
                        <use xlink:href="#monetarization" />
                    </svg>
                </a>
                <a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https://snapdrop.net%20by%20@robin_linus%20&" title="Tweet about Snapdrop" rel="noreferrer">
                    <svg class="icon">
                        <use xlink:href="#twitter" />
                    </svg>
                </a>
                <a class="icon-button" target="_blank" href="https://github.com/RobinLinus/snapdrop/blob/master/docs/faq.md" title="Frequently asked questions" rel="noreferrer">
                    <svg class="icon">
                        <use xlink:href="#help-outline" />
                    </svg>
                </a>
            </div>
        </section>
        <x-background></x-background>
    </x-about>
    <!-- SVG Icon Library -->
    <svg style="display: none;">
        <symbol id=wifi-tethering viewBox="0 0 24 24">
            <path d="M12 11c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 2c0-3.31-2.69-6-6-6s-6 2.69-6 6c0 2.22 1.21 4.15 3 5.19l1-1.74c-1.19-.7-2-1.97-2-3.45 0-2.21 1.79-4 4-4s4 1.79 4 4c0 1.48-.81 2.75-2 3.45l1 1.74c1.79-1.04 3-2.97 3-5.19zM12 3C6.48 3 2 7.48 2 13c0 3.7 2.01 6.92 4.99 8.65l1-1.73C5.61 18.53 4 15.96 4 13c0-4.42 3.58-8 8-8s8 3.58 8 8c0 2.96-1.61 5.53-4 6.92l1 1.73c2.99-1.73 5-4.95 5-8.65 0-5.52-4.48-10-10-10z"></path>
        </symbol>
        <symbol id=desktop-mac viewBox="0 0 24 24">
            <path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7l-2 3v1h8v-1l-2-3h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 12H3V4h18v10z"></path>
        </symbol>
        <symbol id=phone-iphone viewBox="0 0 24 24">
            <path d="M15.5 1h-8C6.12 1 5 2.12 5 3.5v17C5 21.88 6.12 23 7.5 23h8c1.38 0 2.5-1.12 2.5-2.5v-17C18 2.12 16.88 1 15.5 1zm-4 21c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5-4H7V4h9v14z"></path>
        </symbol>
        <symbol id=tablet-mac viewBox="0 0 24 24">
            <path d="M18.5 0h-14C3.12 0 2 1.12 2 2.5v19C2 22.88 3.12 24 4.5 24h14c1.38 0 2.5-1.12 2.5-2.5v-19C21 1.12 19.88 0 18.5 0zm-7 23c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm7.5-4H4V3h15v16z"></path>
        </symbol>
        <symbol id=info-outline viewBox="0 0 24 24">
            <path d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"></path>
        </symbol>
        <symbol id=close viewBox="0 0 24 24">
            <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
        </symbol>
        <symbol id=help-outline viewBox="0 0 24 24">
            <path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"></path>
        </symbol>
        <symbol id="twitter">
            <path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z" />
        </symbol>
        <symbol id="github">
            <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
        </symbol>
        <g id="notifications">
            <path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z" />
        </g>
        <symbol id="homescreen">
            <path fill="none" d="M0 0h24v24H0V0z" />
            <path d="M18 1.01L8 1c-1.1 0-2 .9-2 2v3h2V5h10v14H8v-1H6v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM10 15h2V8H5v2h3.59L3 15.59 4.41 17 10 11.41z" />
            <path fill="none" d="M0 0h24v24H0V0z" />
        </symbol>
        <symbol id="monetarization">
            <path d="M0 0h24v24H0z" fill="none" />
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1.41 16.09V20h-2.67v-1.93c-1.71-.36-3.16-1.46-3.27-3.4h1.96c.1 1.05.82 1.87 2.65 1.87 1.96 0 2.4-.98 2.4-1.59 0-.83-.44-1.61-2.67-2.14-2.48-.6-4.18-1.62-4.18-3.67 0-1.72 1.39-2.84 3.11-3.21V4h2.67v1.95c1.86.45 2.79 1.86 2.85 3.39H14.3c-.05-1.11-.64-1.87-2.22-1.87-1.5 0-2.4.68-2.4 1.64 0 .84.65 1.39 2.67 1.91s4.18 1.39 4.18 3.91c-.01 1.83-1.38 2.83-3.12 3.16z" />
        </symbol>
        <symbol id="icon-theme" viewBox="0 0 24 24">
         <rect fill="none" height="24" width="24"/><path d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/>
        </symbol>
    </svg>
    <!-- Scripts -->
    <script src="scripts/network.js"></script>
    <script src="scripts/ui.js"></script>
    <script src="scripts/theme.js" async></script>
    <script src="scripts/clipboard.js" async></script>
    <!-- Sounds -->
    <audio id="blop" autobuffer="true">
        <source src="/sounds/blop.mp3" type="audio/mpeg">
        <source src="/sounds/blop.ogg" type="audio/ogg">
    </audio>
    <!-- no script -->
    <noscript>
        <x-noscript class="full center column">
            <h1>Enable JavaScript</h1>
            <h3>Snapdrop works only with JavaScript</h3>
        </x-noscript>
        <style>
        x-noscript {
            background: #599cfc;
            color: white;
            z-index: 2;
        }

        a[href="#info"] {
            color: white;
        }
        </style>
    </noscript>
</body>

评论

  1. 蚂蚁
    1 年前
    2023-4-08 11:46:31

    大佬,我是群晖7.1,容器安装好了,也能通过端口访问,但是映射到 /docker/Snapdrop/app 到 装载路径 /app 就无法访问 显示404

    • 博主
      蚂蚁
      1 年前
      2023-4-24 16:49:25

      你要先完成这个步骤:将Docker中的文件拷贝到本地
      之后再做映射,就可以了,我这个方法的原理是将Docker中的文件拷贝出来,方便修改,然后把这个路径映射给Docker。

    • 博主
      蚂蚁
      1 年前
      2023-4-24 16:51:15

      另外,抱歉回复的很晚,近期很长一段时间因为工作原因都没有时间维护Blog

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇