先区分订阅地址、服务器分享链接与完整配置,再判断能否转换。Base64 订阅通常只是多条分享链接的编码包装;原生 JSON 还包含本地监听、DNS 与路由,不能靠换后缀变成订阅。本文适合遇到“订阅无法识别”“JSON 导入失败”或需要跨客户端迁移的用户,提供本地编码方法、字段对应关系与导入后的检查步骤。
先识别内容:订阅地址不等于订阅格式
日常所说的“V2Ray 订阅”并不是一种涵盖所有客户端的统一文件标准。一个以 https:// 开头的订阅地址,只表示客户端需要访问某个接口;服务器返回的正文,才决定它是链接列表、Base64 文本,还是某种配置文件。同一个接口也可能根据请求参数或客户端标识返回不同内容,因此不能只看地址后缀判断兼容性。
| 内容类型 | 常见外观 | 实际保存的内容 | 合适的入口 |
|---|---|---|---|
| 链接列表订阅 | 多行协议链接,或一整段 Base64 | 多个服务器的连接参数 | 订阅分组与更新功能 |
| 单条分享链接 | vmess:// 或 vless:// | 一个服务器的连接参数及备注 | 从剪贴板导入服务器 |
| 完整原生 JSON | 含 inbounds、outbounds 等字段 | 内核的一套运行配置 | 与内核匹配的自定义配置入口 |
取得订阅正文时,先留意是否实际收到了错误页。开头出现网页标签、登录提示,或者“访问已过期”等文字,意味着请求没有得到预期的节点内容。把错误页再次 Base64 编码,只会得到一个编码后的错误页,不会修复订阅。
按用途选格式:日常更新与整套配置分开管理
对 v2rayN、v2rayNG、v2flyNG 来说,服务器列表和运行配置属于不同层级。客户端可以依据服务器参数生成内核配置,但完整配置里包含的本地端口与分流策略,未必能反向装进一条分享链接。选格式时先确定需要迁移的是“节点”,还是“节点加本机策略”。
客户端兼容的链接列表订阅
推荐保留远程订阅地址,由客户端定期或手动获取服务器列表。提供方变更节点时,可以通过更新订阅取得新内容。
适合:日常维护多个服务器、需要持续更新节点列表
单条 VMess / VLESS 分享链接
便于导入一个服务器,也便于逐项核对连接参数。导入后通常是本地服务器记录,不自动继承原订阅的更新关系。
适合:临时测试一个节点、手工迁移少量服务器
与内核匹配的完整 JSON
可以表达入站、出站、DNS 与路由等设置。需要确认目标内核支持相应字段,不能只依据文件扩展名判断。
适合:维护自定义路由、固定本地监听与多出站配置
v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核;v2rayN 的实际能力还要结合所选内核判断。同为 JSON 并不代表配置可以直接通用,同为 VLESS 也不意味着每种传输、安全设置都能被所有目标版本识别。转换前应以目标客户端与内核的实际支持范围为准。
Base64 订阅怎么解码:先去包装,再检查每行
常见的 Base64 订阅制作方式,是把多条分享链接按换行连接,再对整段文本编码。解开外层后,可能看到 vmess:// 和 vless:// 混排。特别要注意:传统 VMess 分享链接本身又包含一层 Base64,因此解开订阅外层,不等于已经解开每个 VMess 节点。
Base64 是编码,不是加密。标准编码常用 +、/ 和尾部的 =;URL 安全变体会使用 -、_,有些输出还省略补位。中文备注应按 UTF-8 处理,否则直接使用字符编码转换可能产生乱码。
下面是可在本地浏览器空白页开发者工具中使用的函数。它只处理传入的文本,不请求网络;示例域名、UUID 和端口用于说明结构,不是可连接的服务。
function decodeBase64Utf8(input) {
let text = input.trim().replace(/\s+/g, "")
.replace(/-/g, "+").replace(/_/g, "/");
if (text.length % 4 === 1) {
throw new Error("Base64 长度无效");
}
text = text.padEnd(Math.ceil(text.length / 4) * 4, "=");
const bytes = Uint8Array.from(atob(text), ch => ch.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeBase64Utf8(input) {
const bytes = new TextEncoder().encode(input);
const binary = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
return btoa(binary);
}
const exampleLink = "vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.com#TLS-demo";
const encodedList = encodeBase64Utf8(exampleLink + "\n");
console.log(decodeBase64Utf8(encodedList));
- 先确认正文是不是已经明文列出协议链接;如果是,直接检查列表,不必再解码。
- 若正文是整段编码文本,用解码函数去掉外层包装,然后按换行拆分,忽略空行。
- 检查每行的协议前缀。只有明确识别为传统 VMess 编码结构时,才继续解开其前缀后的内容。
- 如果解码失败,保留原文排查截断、网页内容或字符替换,不要把多次盲目解码当作修复办法。
VMess 与 VLESS 分享链接:结构不同,不能互换前缀
传统 VMess 链接:JSON 再编码
常见的传统 VMess 分享形式为 vmess:// 加 Base64 编码后的节点 JSON。这份节点 JSON 不是内核完整配置;它没有描述本机所有入站和路由。下面展示编码前的常见字段结构,其中 v 是分享结构版本标识,不是客户端或内核版本号。
{
"v": "2",
"ps": "VMess TLS 示例",
"add": "example.com",
"port": "443",
"id": "11111111-1111-4111-8111-111111111111",
"aid": "0",
"scy": "auto",
"net": "tcp",
"type": "none",
"host": "",
"path": "",
"tls": "tls",
"sni": "example.com"
}
将这段对象序列化后,可以使用前面的编码函数组合出传统链接:"vmess://" + encodeBase64Utf8(JSON.stringify(node)),其中 node 为上述对象。反向解析时移除前缀,再解码并用 JSON.parse 读取。这里的 aid: "0" 对应常见 VMess AEAD 配置,不应因为旧教程而自行改成其他数值。
VLESS 链接:URI 字段与查询参数
VLESS 通常直接使用 URI 结构:用户标识位于 @ 前,服务器地址与端口位于其后,传输和安全参数放在查询部分,备注放在 # 后。中文备注需要百分号编码;字段中的特殊字符也应由 URI 工具正确编码,不能简单拼接未处理的文本。
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.com#TLS-demo
encryption=none是 VLESS 协议层设置,不等于关闭 TLS;是否启用 TLS 由security=tls等设置表达。sni是 TLS 握手使用的服务器名称,不应与 WebSocket 的 HTTP Host 或连接地址随意混用。type=tcp表达示例中的传输类型;改为其他传输后,还需要目标传输对应的参数与服务端支持。- VMess 与 VLESS 的认证和配置结构不同。把
vmess://改成vless://,既不会转换协议,也不会改变服务端。
原生 JSON 如何转换:提取节点,不是保留整套行为
完整配置包含“本地怎样接收流量”和“流量怎样发往远端”两部分。下面是 Xray 风格的精简结构示例:本机只在回环地址监听 SOCKS 端口,再通过一个 VLESS TLS 出站连接示例域名。它用于展示字段层级,不包含可用服务凭据,也不是各内核通用配置。
{
"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": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "example.com"
}
}
}
]
}
| JSON 字段 | 分享链接位置 | 示例值 |
|---|---|---|
settings.vnext[0].address | 主机名 | example.com |
settings.vnext[0].port | 远端端口 | 443 |
settings.vnext[0].users[0].id | URI 用户信息 | 示例 UUID |
streamSettings.security | security 查询参数 | tls |
tlsSettings.serverName | sni 查询参数 | example.com |
inbounds[0].port | 不写入服务器分享链接 | 10808 是本机端口 |
上表中的出站子字段均相对于 outbounds[0]。手动提取时,先选中实际代理出站,再读取该出站的协议和传输参数。不要一律取数组第一项:真实配置的第一项可能是直连出站,也可能存在多个代理出站、链式连接或负载选择。
- JSON 转分享链接:提取一个目标出站能够表达的字段,按对应协议的分享规范生成链接;DNS、路由、本地监听及其他出站另行保存。
- 分享链接转 JSON:先在客户端导入节点,让客户端按当前设置生成内核运行配置;如需手写,除远端字段外,还要明确本地入站和默认出站行为。
- 链接列表转 Base64 订阅正文:将有效分享链接逐行连接,再进行一次 UTF-8 Base64 编码。得到的是订阅正文,不是能够远程更新的订阅地址。
- Base64 转完整 JSON:先解码识别内容,再逐节点转换。直接把编码文本放进
outbounds,不符合内核配置结构。
客户端导入与迁移:先备份,再用单节点验证
手动转换前先导出或备份现有设置,并保留原订阅地址。不要直接覆盖正在使用的订阅分组;新建一个测试分组导入少量节点,可以区分“格式解析失败”和“服务器连接失败”。下列菜单按常见中文界面描述,具体文字可能随客户端版本变化。
迁移方案:服务器信息与本机配置分别处理
桌面端:v2rayN
- 远程地址使用「订阅分组」→「订阅分组设置」添加,再更新目标分组。
- 单条链接使用「服务器」→「从剪贴板导入批量 URL」,先检查导入结果。
- 核对本地监听端口、所选内核与路由设置,不把远端 443 当成本机代理端口。
安卓端:v2rayNG / v2flyNG
- 远程订阅在订阅分组设置中添加;单条链接使用主界面的剪贴板导入入口。
- v2rayNG 按 Xray 能力检查参数,v2flyNG 按 V2Fly 能力检查参数。
- 重新确认 VPN 授权与分应用设置,这些本机选项不会随普通节点链接迁移。
同一订阅可以作为两端的共同来源,但更新时点、协议支持与本机策略仍需分别核对。
导入后先打开节点编辑界面,对照原始内容检查地址、端口、用户标识、传输类型与 TLS 参数,再启动连接查看日志。如果列表正常但握手失败,应检查连接参数和服务端状态;如果节点数量为零,则优先排查响应正文与导入入口,而不是先修改路由。
- 本地链路:使用系统代理或手动指定代理的应用,应连接客户端实际监听的地址与端口。示例中的
127.0.0.1:10808不能作为所有安装的默认值。 - 远端链路:连接超时、认证失败、TLS 名称不匹配属于不同问题,需依据日志分别处理,不要同时改动全部字段。
- 更新关系:从剪贴板导入的静态节点不会因原订阅地址更新而必然同步;需要自动更新时,应保存订阅地址及所属分组。
订阅转换常见问题:能解码不代表能连接
Base64 解出来还是 vmess 开头,是不是没解完?
这通常是正常的外层订阅列表。先按行拆分;对于传统 VMess 链接,再取 vmess:// 后的部分解码为节点 JSON。不要对整份混合链接列表重复解码,否则会把 URI 标点也当成编码内容处理。
拿到 JSON,为什么“从剪贴板导入”提示没有服务器?
先看顶层字段。若含 inbounds、outbounds,它可能是完整内核配置,应使用目标版本支持的自定义配置入口,或者按本文步骤提取单个代理出站。剪贴板分享链接入口不是通用 JSON 导入器。
改成 Base64 以后,为什么仍然导不进客户端?
先解码回原文确认内容没有损坏,再检查每行是否为目标客户端支持的协议链接。Base64 只改变文本表示,不会补齐缺失的用户标识,不会把网页转换成节点,也不会增加内核不具备的协议支持。
转换后节点能用了,为什么分流规则没跟过来?
普通分享链接主要表达单个远端节点,不负责完整迁移 DNS、路由和分应用设置。回到目标客户端核对本机策略;需要复现整套路由时,保留原生配置并确认内核字段兼容,不能把节点连接成功当作配置迁移完成。
最终判断顺序是:先确认拿到的是正确正文,再确认编码层次,然后核对节点字段,最后检查目标内核和本机流量入口。订阅、分享链接与原生 JSON 各有用途;只有明确每一步保留什么、丢失什么,手动转换才不会把连接问题和配置问题混在一起。相关概念可继续查看名词解释,路由与内核设置可查阅配置进阶。