搭建订阅转换服务 (无VPS版)

提到订阅转换不可避免地想到隐私问题,但是搭建后端需要服务器支持,除非只在本地使用。之前我也在本地计算机搭建过,因为本地搭建必须开启计算机才能使用,体验非常不方便,尤其是移动端使用时。遂放弃,只好继续使用别人提供的服务,泄露就泄露好了,反正也不值钱 (?)

但是在昨天,无意间看到 buliang0 大佬分享的视频,他分享了一种通过搭建反代站点,防止自己在使用别人后端时信息被泄露的方法。如果后端可以通过这种方式代替,前端理论上只是一个网站而已,既然 Github Pages 可以部署博客,那区区一个网站应该也可以吧?

不幸的是,通过搜索,我并没有在网上找到相关教程,只找到在 VPS 上搭建的方法。但感觉应该可以,于是前端小白的我打算试一试,经过一晚上的折腾,还真成功了,于是便有了本篇文章。

◇ 搭建 (伪) 订阅转换后端

具体教程参见大佬的视频,视频地址:链接

主要原理: 利用 Cloudflare Worker 搭建反代工具,通过随机化服务器地址和账号密码,解决用户的隐私问题。

这里简要描述一下搭建过程:

- 创建 Worker

打开 Cloudflare,创建一个 Worker。

- 编辑代码

填写下面项目中 worker.js 的代码。

项目地址:https://github.com/bulianglin/psub
(代码具体实现过程还没来得及看,有时间了研究研究。)

- 配置 Worker

左边侧栏:“Workers 和 Pages” > “KV” > “创建命名空间”,填写任意名称,如 sub

回到刚才创建的 Worker,选择 “设置” > “变量”。

  1. 添加环境变量:
    变量名称:BACKEND值: 自己选一个订阅转换后端的地址,比如 https://sub.xeton.dev
  2. KV 命名空间绑定:
    变量名称:SUB_BUCKET值: 刚才创建的命名空间。

⚠ “KV 命名空间” 可以换成 “R2 存储桶”。

- 绑定个人域名 (可选)

两种方法任选其一:

自定义域

打开刚才创建的 Worker,选择 “Custom Domains” > “添加自定义域”:
输入自定义域名,例如:subconverter.example.com

路由

打开刚才创建的 Worker,选择 “Routes” > “添加路由”:
输入自定义域名,例如:subconverter.example.com/*
区域选择自己绑定的域名,然后去 DNS 解析添加一条记录。地址可以随便填,但一定要打开代理。如图所示:
 DNS 解析

- 使用

至此,后端反代设置成功,以后输入后端地址的时候填自己的网址即可,记得加上 /sub? 后缀,例如:https://subconverter.example.com/sub?

如果要临时修改 BACKEND 中设置的地址,可以在转换链接末尾添加 &bd=, 例如 &bd=https://sub.example.dev,这样就可以覆盖 Worker 中设置的环境变量。

◇ 搭建订阅转换前端

后续更新:

今天发现前面的后端反代已经更新了代码,直接访问反代网址就可以显示简单的前端页面。但是如果有自定义需求,建议还是自己搭建一个。

sub-web 前端项目地址:https://github.com/CareyWang/sub-web

网上的教程都是 VPS Linux 环境,这里使用本地 Windows + Cloudflare Pages 的方式搭建。
(为什么不使用 Github Pages?因为失败了,失败原因未知,待研究···)

后续更新:

已成功解决 Github Pages 的问题,方法见后文。

搭建步骤如下:

- 安装 Node 与 Yarn

因为博客项目本身就需要 Nodejs,所以电脑已经安装过了。至于 Yarn,虽然不知道干什么的,不过先搜搜看看 Windows 有没有:

1
scoop search yarn

结果当然是有啦,这就好办了。

1
2
3
4
5
6
Results from local buckets...

Name Version Source Binaries
---- ------- ------ --------
yarn-np 1.22.19 dorado
yarn 1.22.19 main

直接安装:

1
scoop install yarn

什么是 Yarn?

Yarn 是一个用于管理 JavaScript 包依赖的包管理工具。它的主要作用是帮助开发人员在 JavaScript 项目中管理依赖关系、包的版本和安装过程。
尽管 npm 是 Node.js 的官方包管理工具,但在过去,它有一些性能和安全性方面的问题,这导致了 Yarn 的出现。Yarn 在功能上类似于 npm,但它旨在解决这些问题,提供更快、可靠和安全的包管理体验。因此,开发人员可以选择在他们的 Node.js 项目中使用 npm 或 Yarn,根据个人偏好和项目需求来决定。

- 下载并安装 sub-web

先在 Github 上 fork 一份源代码,方便后续升级更新。然后克隆到本地:

1
2
git clone https://github.com/<username>/sub-web.git
cd sub-web

在项目目录中安装构建依赖项:

1
yarn install

然后就报错了···
报错

通过查看报错信息,可以得知,是 Node 版本不兼容,它需要的是 8, 10, 12, 14, 16, 17 版本,而本机装的是最新版 v21.0.0。

如果需要安装旧版,可以通过 Versions 这个 bucket 进行安装:

1
2
3
4
# 添加 versions 源
scoop bucket add versions
# 搜索 node
scoop search nodejs

Versions 用于存储那些不同软件版本的软件包,这些软件包可能是历史版本,也可能是测试版本或开发版本。当使用 Scoop 安装软件时,你可以从 “Scoop Versions” 中选择要安装的特定版本,并且可以很方便地在不同版本之间切换。

结果显示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Results from local buckets...

Name Version Source Binaries
---- ------- ------ --------
nodejs-lts 18.18.2 main
nodejs 21.0.0 main
nodejs010 0.10.48 versions
nodejs012 0.12.18 versions
nodejs10 10.24.1 versions
nodejs11 11.15.0 versions
nodejs12 12.22.12 versions
nodejs14 14.21.3 versions
nodejs16 16.20.2 versions
nodejs18 18.18.2 versions
nodejs4 4.9.1 versions
nodejs5 5.12.0 versions
nodejs6 6.17.1 versions
nodejs7 7.10.1 versions
nodejs8 8.17.0 versions
nodejs9 9.11.2 versions

这里我们安装 16 版本即可:

1
2
3
4
# 安装 nodejs16
scoop install nodejs16
# 切换 nodejs 版本
scoop reset nodejs16

查看版本,发现已经切换过来了:

1
2
$ node -v
v16.20.2

重新输入命令安装构建依赖项,可以成功运行了,过程稍微有点长,需耐心等待。

1
yarn install

然后输入以下命令,使用 webpack 运行 Web 客户端进行本地开发:

1
yarn serve

浏览器访问 http://localhost:8080/, 应该可以看到前端 sub-web 的预览了。
(该界面在完成调试前,不要退出。)

- 修改配置文件

打开项目中的 /src/views/Subconverter.vue 文件:

修改默认后端地址

找到 backendOptions:,替换后面的 http://127.0.0.1:25500/sub? 为前面自己搭建的反代网址,如:https://subconverter.example.com/sub?

添加远程规则

找到 remoteConfig:,根据里面的示例代码,添加自己的远程规则地址,或是在网上找别人的远程规则。

配置保存后,打开网页检查是否配置成功。

界面优化

通过前面提到的 &bd= 字符,可以很容易地在前端内建多个反代后端,但是添加后发现,默认的 后端地址 下拉框无法显示 label 标签,只有一堆 url 字符,感觉很丑,而且不方便区分。于是照着 远程配置 的代码样式修改了一下,但是后面的按钮又无法显示了。虽然两个按钮用处不大,但怎么可以没有!!

最后通过一顿查资料和各种尝试,把下拉框和按钮两个元素改成了并列,然后添加 div 标签,同时添加了 flex 属性,保证两个元素在同一行显示,完美成功~

代码修改结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<el-form-item label="后端地址:">
<div style="display: flex; align-items: center;">
<el-select v-model="form.customBackend" allow-create filterable placeholder="请选择" style="width: 100%">
<el-option-group v-for="group in options.backendOptions" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-option-group>
</el-select>
<el-button slot="append" @click="gotoGayhub" icon="el-icon-link">项目仓库</el-button>
</div>
</el-form-item>

<el-form-item label="远程配置:">
<div style="display: flex; align-items: center;">
<el-select v-model="form.remoteConfig" allow-create filterable placeholder="请选择" style="width: 100%">
<el-option-group v-for="group in options.remoteConfig" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-option-group>
</el-select>
<el-button slot="append" @click="gotoRemoteConfig" icon="el-icon-link">配置示例</el-button>
</div>
</el-form-item>

标签显示效果:
标签显示效果

按钮显示效果:
按钮显示效果

- 打包

我们现在需要打包,生成一个发布目录。
首先通过 ctrl+c 停止调试程序,然后执行下面的命令进行打包:

1
yarn build

完成后会在项目文件夹生成一个 dist 目录,这个目录即为网页的发布目录。

你可以手动将这个文件夹部署到任何你想部署的地方,不过方便起见,我们可以通过 Github Action 自动构建并将生成的目录上传到指定分支。

- 自动构建

编辑配置文件

打开项目中的 \.github\workflows 文件夹,可以看到里面有 2 个文件:build.ymldocker-build-push.yml

其中,build.yml 使用了官方的 Action:upload-artifact,它可以将虚拟环境中的指定文件打包上传到 Ac­tions 页面。
具体来说,当用户将本地 master 分支提交到远程仓库时,Github Action 会自动构建,并将生成的 dist 目录以压缩包的形式上传到 Ac­tions 页面。

至于 docker-build-push.yml,应该是利用 docker 进行打包部署的,因为没有使用,所以还没来得及具体研究···

后续更新:

已研究,参见:链接

我们主要在 build.yml 这个文件的基础上进行修改:

\.github\workflows 目录下新建一个文件,随便取一个名称,例如:pages.yml,然后将 build.yml 里的内容粘贴进去,参考之前博客的部署方法 (链接),可以使用 peaceiris/actions-gh-pages 来操作,最后的修改结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
name: Pages

on:
push:
branches: [ master ]

jobs:

build:
name: Build
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [16.x]

steps:
- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Cache NPM dependencies
uses: actions/cache@v2
with:
path: node_modules
key: ${{ runner.OS }}-npm-cache-sub
restore-keys: |
${{ runner.OS }}-npm-cache-sub

- name: Get dependencies and build
run: |
yarn install
yarn build

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist

因为之前那两个文件目前用不上,直接删掉又不太好 (万一以后用得上呢),所以把触发动作修改一下:

1
2
3
4
5
6
on:
push:
#branches: [ master ]

branches-ignore:
- '*'

将原来的 branches 注释掉,然后添加 branches-ignore,这样以后不管推送哪个分支都不会触发工作流啦。

推送并部署

将修改后的项目推送到远程仓库:

1
2
3
git add .
git commit -m "提交说明"
git push origin master

推送后等待片刻,也可以在 Actions 页面查看工作流运行情况,成功后会出现一个新的分支 gh-pages,里面的内容即生成的 dist 目录内容。

Settings > Pages > Build and deployment 中将 branch 改为 gh-pages
github pages

理论上稍等片刻访问上面显示的网址即可打开搭建的前端页面,但我这边显示白屏,开始还以为是打包后的文件有问题,后来试着把它们传到 Cloudflare Pages,发现成功了?于是弃用 Github Pages,转到 Cloudflare Pages。

Github Pages 的解决方法:

Github Pages 默认的网址格式是:https://<username>.github.io/sub-web/,由于我在 Blog 项目中使用了自定义域名,所以这个仓库的网址格式自动变成了:https://example.com/sub-web/,可能是由于 DNS 解析时无法找到这个地址,因为它指向了 Blog 项目,但是目录中又没有 sub-web 这个文件夹,于是导致网站无法打开。

解决方法是重新设定一个自定义域名就可以啦,例如:https://subweb-github.example.com。在 Pages 的设置界面填好网址后去添加一个 DNS 解析,地址和 Blog 项目中添加一样,指向 Github 即可。参考:链接

- 将项目部署到 Cloudflare Pages

在 Cloudflare 中创建一个 Page,选择 “连接到 Git”,登录 Github 账号选择 sub-web 仓库和 gh-pages 分支,因为已经在 Github 构建好了无需重复构建,直接点击 “保存并部署” 即可。

Cloudflare 会自动进行操作,然后分配一个域名地址,成功后就可以访问站点了。如果想使用自己的域名,直接点击 “自定义域” 即可一键添加自定义域名,非常方便。

◇ 搭建完成

至此,前端、(伪)后端就全部搭建完成了。没有 VPS 的 me🥺 终于也可以实现订阅转换自由了~

◇ 参考内容

  1. sub-web搭建. https://help.mints7.cc/da-jian-jiao-cheng/subweb-da-jian
  2. GitHub Actions 入门教程. https://p3terx.com/archives/github-actions-started-tutorial.html