订阅地址负责获取内容,Base64 负责包装文本,分享链接描述单个节点,原生 JSON 描述内核运行配置。本文适合遇到“订阅有内容却导不进”“JSON 不能转链接”等问题的用户:先辨认输入,再用离线方式解码,最后通过客户端生成配置并核对字段,避免把路由、DNS 或安全参数在转换时丢掉。
一、先区分订阅地址、订阅正文与节点配置
一个以 https:// 开头的订阅地址只是获取入口,不代表其响应一定采用某种格式。服务端可以返回 Base64 文本、逐行分享链接,也可能返回某个客户端专用的配置。判断能否导入,应看下载到的正文,而不是地址后缀是否为 .txt 或 .json。
常见的 Base64 订阅是“多条节点分享链接,用换行符连接,再对全文编码”。这里往往有两层编码:外层是整个列表,内层可能是每条 vmess:// 后面的节点 JSON。解开外层并不会自动得到完整内核配置。Base64 是可逆编码,不提供保密能力。
| 对象 | 常见外观 | 包含内容 | 处理入口 |
|---|---|---|---|
| 订阅地址 | https:// 开头 | 远程资源位置,可能带访问令牌 | 订阅分组设置 |
| Base64 订阅正文 | 较长编码文本 | 通常是编码后的逐行分享链接 | 订阅更新或先离线解码 |
| 分享链接列表 | vmess://、vless:// | 单个或多个节点的连接参数 | 从剪贴板导入 |
| 原生 JSON | 含 inbounds、outbounds 等键 | 入站、出站以及可选 DNS、路由配置 | 自定义配置入口 |
判断:先看正文,再选导入入口
正文已经是逐行分享链接,就不要再重复解码;正文包含完整入站和出站结构,就不要把它当作订阅地址添加。若返回登录页面或错误页面,应先修复订阅访问,而不是继续转换。
二、VMess 与 VLESS 分享链接怎样表达参数
常见的 vmess:// 分享格式把一个节点描述 JSON 编码后接在协议头后面。解码后常见字段包括 add、port、id、net、host、path 和 tls。这里的 JSON 属于分享格式,不是可以直接交给内核运行的原生 JSON。
下面是用于阅读结构的 VMess 节点描述。地址与 UUID 均为文档示例,不对应可连接服务;v: "2" 表示这类分享格式的版本标记,不是客户端版本。现代 VMess 节点通常使用 aid: "0",实际值仍应以服务端配置为准。
{
"v": "2",
"ps": "示例-VMess-WS",
"add": "example.com",
"port": "443",
"id": "123e4567-e89b-42d3-a456-426614174000",
"aid": "0",
"scy": "auto",
"net": "ws",
"type": "none",
"host": "example.com",
"path": "/proxy",
"tls": "tls",
"sni": "example.com"
}
VLESS 分享链接通常直接采用 URI 结构。用户名位置存放 UUID,主机与端口表示连接目标,查询参数描述传输和安全层,井号后面是节点备注。下面示例采用 WebSocket 与 TLS,不涉及额外的流控参数。
vless://[email protected]:443?encryption=none&security=tls&type=ws&host=example.com&path=%2Fproxy&sni=example.com#示例-VLESS-WS
security=tls表示传输安全层使用 TLS;encryption=none是 VLESS 的协议参数,两者并不矛盾。host在此表示 WebSocket 请求的 Host;sni用于 TLS 握手。二者用途不同,即使示例取值相同,也不能在转换时互相替代。path=%2Fproxy解码后是/proxy。路径含问号、井号或空格时,应按 URI 参数编码,不能直接拼接。#后的备注不改变连接方式。中文备注应使用 UTF-8 与百分号编码,以减少不同导入器之间的歧义。
三、离线解码与重新编码 Base64 订阅
处理真实订阅时,应把订阅地址、UUID 和解码正文都视为敏感数据。不要把它们提交到不熟悉的在线转换页面。可以在本地空白页面的浏览器开发者工具中执行经过检查的代码;操作前确认页面没有其他脚本读取输入,并注意开发者工具可能保留历史记录。
以下函数只进行本地字符串转换,不发起网络请求。解码函数同时兼容常见标准 Base64 和 URL 安全字符,容忍编码文本中的换行,并补齐缺失的尾部等号。若输入本身不是 Base64,仍应检查来源,不能靠反复编码、解码碰运气。
function decodeBase64Utf8(input) {
const normalized = input.trim()
.replace(/\s+/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
if (normalized.length % 4 === 1) {
throw new Error("Base64 长度不合法");
}
const padded = normalized.padEnd(
Math.ceil(normalized.length / 4) * 4, "="
);
const bytes = Uint8Array.from(atob(padded), c => c.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeBase64Utf8(text) {
const bytes = new TextEncoder().encode(text);
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
把原始订阅正文作为字符串传给 decodeBase64Utf8,检查结果是否按行出现协议头。若要生成传统 Base64 订阅,应先整理有效分享链接,再调用 encodeBase64Utf8(links.join("\n"))。不要对整个列表执行 URL 解码,否则节点参数中原本编码的分隔符可能被提前还原。
- 去掉文本开头可能存在的字节顺序标记,按
\r?\n拆分行,并移除空行。 - 逐行确认协议头;错误页、流量说明和公告文字不应混入节点列表。
- 仅在需要查看 VMess 节点字段时,再解码单条链接中
vmess://后面的部分。 - 重新编码后做一次反向解码,确认节点行数和中文备注未改变,再导入客户端测试。
四、通过客户端导入、导出与生成配置
日常迁移优先让客户端解析分享链接,再由客户端生成对应内核配置。这样可以减少手写字段错误,但仍要核对传输参数。v2rayN 桌面版与不同版本的菜单文字可能略有调整,下面按常见菜单名称说明;若找不到同名项,应寻找相同功能,而不是改用不相关的自定义配置入口。
-
备份分组
先记录当前活动服务器与订阅分组,保存原始订阅地址。测试内容放进单独分组,避免批量导入后覆盖原有使用习惯。
-
添加订阅
在 v2rayN 打开「订阅分组」→「订阅分组设置」,新增分组并填写订阅地址。回到「订阅分组」执行「更新全部订阅(不通过代理)」;若该地址需要代理访问,再选择对应的通过代理更新项。
-
导入单条
复制完整的分享链接,在「服务器」→「从剪贴板导入批量 URL」执行导入。这里只粘贴节点链接;本地 JSON 文件应通过自定义配置功能处理。
-
导出再核对
选中节点并右键,使用当前版本提供的分享 URL 导出或复制功能。将导出结果重新导入测试分组,打开编辑窗口,对照地址、端口、UUID、传输类型、SNI 和路径。
-
验证连接
设置测试节点为活动服务器,查看内核启动日志,再验证实际请求。只有客户端提供“导出完整配置”或同类功能时才导出原生 JSON;复制分享链接不等于导出运行配置。
安卓端 v2rayNG 常见操作是主界面「+」→「从剪贴板导入」,订阅地址则在「订阅分组设置」中添加,再执行更新订阅。v2flyNG 也应按其界面区分订阅管理与单节点导入。两款安卓客户端使用的内核家族不同,解析到一个 VLESS 链接并不保证具备该链接要求的全部传输能力,尤其要核对 REALITY 等功能。
五、分享链接怎样映射到原生 JSON
原生 JSON 的结构由目标内核决定,不由文件扩展名决定。一个完整运行配置除了远端节点,还需要本地入站以及必要的出站选择。下面给出 Xray 风格的 VLESS、WebSocket、TLS 示例,用于展示与上文 URI 的字段映射。示例地址不可作为实际服务使用;本机若已有程序占用 10808,应换用未占用端口,并同步修改调用方。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "123e4567-e89b-42d3-a456-426614174000",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.com",
"allowInsecure": false
},
"wsSettings": {
"path": "/proxy",
"headers": {
"Host": "example.com"
}
}
}
}
]
}
- URI 主机与端口映射到
settings.vnext中的address、port;UUID 映射到users[].id。 type=ws映射到streamSettings.network,security=tls映射到同层的security。sni映射到tlsSettings.serverName;WebSocket 的 Host 与路径进入wsSettings。- 本地监听地址、入站端口和日志级别来自运行环境,不来自分享链接。不要把服务器的
443填成本地 SOCKS 监听端口。
对于 VMess,出站协议和用户字段需要按 VMess 结构生成,不能只把上述 protocol 改成 vmess 就视为完成。对于带 REALITY、特定指纹或流控的 VLESS 链接,也必须使用目标内核支持的对应结构,并保留公钥、短标识等必要参数。JSON 语法通过仅代表格式合法,不代表内核支持或服务端参数正确。
六、哪些转换能保留信息,哪些不能
“JSON 转订阅”常被误认为是把文件做一次 Base64 编码。实际至少有两步:先从配置中识别可分享的代理出站,将它们转成客户端理解的 URI,再按订阅接收端要求包装。若直接编码完整 JSON,解码结果仍然是 JSON,不会凭空变成节点列表。
客户端导出分享链接
推荐对客户端已经识别为普通节点的条目进行导出,减少字段映射失误。导出后仍需检查安全层、传输参数和目标客户端兼容性。
适合:迁移单节点、整理个人节点列表
离线转换节点字段
只处理明确支持的协议与参数,遇到不认识的字段时停止并记录。不要静默丢弃流控、SNI 或传输设置来换取“导入成功”。
适合:少量节点核对、排查编码与 URI 转义问题
保留完整原生配置
保留入站、DNS、路由与多出站关系,在兼容的内核中以自定义配置方式运行。跨内核迁移时需逐项检查字段。
适合:复杂分流、链式出站、依赖完整运行环境的配置
原生配置中可能包含直连出站、阻断出站、负载选择与按域名分流规则。这些不属于单节点 URI 的表达范围。即使提取出了所有代理服务器,原来的“哪些请求走哪个出站”也不会随分享链接迁移。转换后的节点可以连接,不等于原来的路由策略已经恢复。
判断:迁移节点与迁移配置分开做
只需要连接同一台服务器时,导出分享链接并逐字段核对;需要保留 DNS、路由或多出站关系时,备份完整配置,再在目标客户端单独恢复运行策略。
七、订阅转换常见问题与处理顺序
订阅更新成功,为什么节点列表还是空的?
先查看响应正文是否真的包含节点。若解码结果以 HTML 标签开头,通常拿到的是登录页或访问错误页;若是原生 JSON,应使用匹配的配置入口。再检查分组筛选条件,避免节点已导入却被当前视图隐藏。
Base64 解码后中文备注乱码怎么办?
用 UTF-8 字节解码,不要直接把 atob 返回的字节字符串当中文文本。可以使用本文的 TextDecoder 方法。若只有 URI 的井号备注仍呈现百分号编码,应只对备注部分执行 URI 解码。
JSON 转出来的链接能导入,却连不上?
先对照地址、端口与 UUID,再检查 TLS 的 SNI、WebSocket 的 Host 和路径。若原配置使用 REALITY 或其他特定能力,还要确认目标内核支持以及参数完整。不要通过关闭证书验证掩盖转换遗漏。
原来的国内直连规则怎么没有了?
分享链接通常只带单节点信息,不携带完整路由。回到目标客户端的路由设置恢复分流策略,或使用兼容的完整原生配置。检查默认出站,避免把直连出站误认为需要导出的代理节点。
把订阅地址发给转换网站后要做什么?
若无法确认对方如何保存输入,应在服务提供方的管理界面重置订阅令牌,再到客户端替换地址。令牌重置未必同时更换已有节点凭据;若节点链接也已泄露,还需按服务方能力更换相应凭据。
最后按“输入类型正确 → 解码文本正确 → 节点字段完整 → 内核能力匹配 → 实际请求成功”的顺序验收。每次只改变一个环节,并保留转换前的文本备份。这样遇到导入失败、TLS 握手报错或分流变化时,能够定位具体丢失的字段,而不是反复更换格式。