订阅地址是更新入口,Base64 是编码方式,分享链接描述单个节点,内核 JSON 则可以描述整套运行配置。本文适合遇到“浏览器能打开、客户端却导不进”的用户:先辨认内容,再选择 v2rayN 或 v2rayNG 的导入入口,最后判断转换是否会丢失路由、DNS 或传输参数。
一、订阅地址、Base64 与 JSON 不在同一层
“V2Ray 订阅”不是一种由文件扩展名决定的统一格式。常见流程是:客户端访问一个 HTTPS 地址,取得文本,解析其中的节点,再写入自己的配置列表。地址负责获取和更新;响应正文才决定解析方式。因此,地址末尾没有扩展名,或者带有 .txt,都不足以判断它能否导入。
订阅地址与节点列表
推荐常见响应是逐行排列的分享链接,或对整份链接文本做一次 Base64 编码。保留订阅入口,后续才能重新获取节点变化。
适合:需要在多个设备上持续更新服务列表的用户。
单条分享链接
以 vmess://、vless:// 等前缀识别协议,通常包含一个节点的连接参数。导入后一般是一次性副本,不自动获得订阅更新能力。
适合:临时迁移一个节点,或逐项核对连接参数。
内核原生 JSON
可包含入站、出站、DNS、路由和日志设置。它属于指定内核的配置,不等同于图形客户端的节点列表,也不等同于客户端数据备份。
适合:需要保留多出站、特殊路由或完整内核设置的场景。
Base64 不提供加密保护。订阅令牌、节点身份信息即使变成一长串字符,仍可被还原。不要把完整订阅正文提交到公开转换网站,也不要在求助截图中展示地址的查询参数。
二、vmess:// 与 vless:// 的结构差异
常见 VMess 分享格式是 vmess:// 后接 Base64 编码的 JSON 对象。这个对象经常出现 add、port、id、net、tls 等字段,但它只是分享格式中的节点描述,不是可以直接交给 Xray 启动的完整配置。
| 检查项 | 常见 VMess 分享格式 | 常见 VLESS 分享格式 |
|---|---|---|
| 主体结构 | 协议前缀后接 Base64 JSON | URI 用户信息、主机、端口与查询参数 |
| 节点身份 | JSON 中的 id | URI 中 @ 前的用户信息 |
| 传输方式 | 常见字段 net | 常见查询参数 type |
| TLS 与服务名 | 常见字段 tls、sni | 常见参数 security、sni |
| 备注 | 常见字段 ps | # 后的片段,通常经过百分号编码 |
VLESS 链接通常不是“把整条链接再解一次 Base64”。它的参数还可能包含 flow、fp、pbk、sid,分别涉及流控、指纹与 REALITY 参数。具体名称及接受范围取决于客户端版本,不能仅凭协议前缀判断所有参数都受支持。
- 端口:远端使用
443不代表一定启用了 TLS,应同时核对安全层设置。 - 路径:WebSocket 路径中的
/可能写成%2F;必须按 URI 规则解码,不能简单删除百分号。 - 域名:服务器地址、TLS 的 SNI、WebSocket 的 Host 是不同字段,服务端要求相同时才填写相同值。
- 换行:逐行节点列表通常一行一条链接;聊天工具插入的硬换行可能截断查询参数。
三、Base64 订阅如何解开,为什么有时需要两层解析
假设响应正文是“多条 VMess 链接组成的文本,再整体进行 Base64 编码”。第一层解码得到逐行链接;每条 vmess:// 后的载荷仍需单独解码,才能看到节点字段。这是两种包装层次叠加,不是所有订阅都固定需要解码两次。
- 先检查原文。已经以
vmess://或vless://开头的逐行文本,不需要整体解码。 - 如果看起来是 Base64 文本,再尝试解码一次,并检查结果是否为链接列表。
- 如果解码后出现网页标签、登录提示或错误信息,回到获取环节处理,停止格式转换。
- 若结果是 JSON,检查其字段结构。JSON 数组、内核配置和服务接口返回值,不能只因语法有效就互相替代。
下面是离线处理文本的原生 JavaScript 函数,仅做编码与解码,不发出网络请求。它兼容常见 Base64URL 字符,并使用 UTF-8 处理中文备注。应在可信的本地环境使用,不要将真实内容粘贴到不熟悉页面的控制台。
function decodeBase64Text(source) {
const normalized = source.trim()
.replace(/\s+/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
const padded = normalized.padEnd(
Math.ceil(normalized.length / 4) * 4, "="
);
const bytes = Uint8Array.from(
atob(padded), char => char.charCodeAt(0)
);
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeBase64Text(text) {
const bytes = new TextEncoder().encode(text);
let binary = "";
for (const byte of bytes) {
binary += String.fromCharCode(byte);
}
return btoa(binary);
}
判断方法:先确认解码结果,再决定导入入口
结果是逐行分享链接,就按节点列表处理;结果包含 inbounds、outbounds 等运行配置字段,就进一步核对内核配置结构。反复编码无法修复错误响应,也无法补齐缺失的协议参数。
四、v2rayN 与 v2rayNG 分别从哪里导入
图形客户端一般把“服务器节点”“订阅分组”和“自定义完整配置”分开管理。常规节点导入器负责识别分享链接;订阅设置保存更新地址;自定义配置入口处理完整 JSON。不要把三种内容全部粘贴到订阅地址框中。
导入方案:按内容选择桌面端与安卓端入口
桌面端:v2rayN
- 单条或多条分享链接:复制后使用「服务器」→「从剪贴板导入批量 URL」。
- 订阅地址:在「订阅分组」→「订阅分组设置」添加 URL,再执行更新订阅。
- 完整 JSON:查找「服务器」菜单中的自定义配置服务器入口,并选择与配置匹配的内核。
安卓端:v2rayNG
- 分享链接:点击右上角「+」→「从剪贴板导入」。
- 订阅地址:进入侧边菜单「订阅分组设置」,添加分组与 URL,返回列表执行「更新订阅」。
- 完整 JSON:使用「+」菜单中的自定义配置导入项,不要作为普通节点链接导入。
上述为常见界面文案,不同版本可能略有调整;以当前菜单中的剪贴板、订阅分组与自定义配置功能为准。
v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核。某份 JSON 能在 v2rayNG 运行,并不意味着换到 v2flyNG 后仍可原样运行。尤其涉及 REALITY、特定传输设置或内核专用字段时,应先核对目标内核支持范围。
五、三种格式如何转换,哪些信息无法带走
分享链接与 Base64 订阅之间的转换,通常只改变外层包装:将多条完整链接用换行连接,再进行 UTF-8 Base64 编码,即可得到常见的静态订阅正文。但只有正文还不是可更新的订阅服务;客户端仍需要能够获取它的地址,以及后续维护内容的机制。
| 转换方向 | 可执行方式 | 主要限制 |
|---|---|---|
| Base64 订阅 → 分享链接 | 整体解码一次,保留每条链接与换行 | 不能从正文还原原订阅令牌、更新周期或接口响应头 |
| 分享链接 → Base64 正文 | 每行一条完整链接,按 UTF-8 编码后整体转 Base64 | 静态内容不会自动跟随原订阅更新 |
| 分享链接 → 内核 JSON | 解析协议、安全层和传输参数,生成相应出站 | 还需配置入站、路由、DNS 等运行环境 |
| 完整 JSON → 分享链接 | 选定一个可表达的远端出站,逐项映射参数 | 通常无法保留多出站协作、路由规则与完整 DNS 策略 |
转换 JSON 时,不能只提取服务器、端口和身份字段。以 WebSocket 加 TLS 为例,至少还要核对传输类型、路径、Host、TLS 开关与 SNI;以 VLESS 配合 REALITY 为例,还要核对公钥、短标识及相关流控参数。少一项时,客户端可能显示“导入成功”,但连接仍会失败。
- 先确认输入结构:分享格式里的 VMess JSON 与内核
outbounds中的对象不是同一套字段。 - 再选择目标:完整配置中有多个远端出站时,明确要导出哪一个,不要把直连或阻断出站当成节点。
- 逐项比对:导入目标客户端后打开编辑页,核对安全层、传输路径与协议特有字段。
- 最后验证:先确认内核能启动,再测试请求;节点可用不等于原配置的分流行为已恢复。
迁移建议:需要保留分流时,优先保留完整配置
如果目标只是迁移服务器列表,可以使用分享链接;如果目标是复现原来的 DNS 与路由行为,应保留完整 JSON,并在目标内核上核对兼容性,不要把分享链接当作整套配置的备份。
六、订阅与转换常见问题
浏览器能打开订阅,为什么客户端显示零个节点?
先查看响应是否真的是链接列表或它的 Base64 包装。浏览器可能依赖登录状态,而客户端拿到的是登录页;服务端也可能按请求信息返回不同内容。检查订阅分组里的 URL 是否完整,再确认服务提供方给出的格式是否适用于目标客户端。
解码后中文备注变成乱码,还能继续导入吗?
先使用 UTF-8 解码,不要把 atob() 的结果直接当作中文字符串。若只是备注损坏,连接字段未必有问题,但仍应重新检查原文;若路径或查询参数同时损坏,应停止导入,避免带着错误参数测试。
完整 JSON 语法正确,为什么仍然启动失败?
JSON 语法检查只确认引号、逗号等结构。接着查看内核日志中的具体字段路径,检查是否使用了目标内核不支持的字段、是否缺少运行必需配置,以及本地监听端口是否冲突。不要通过重复 Base64 编码处理启动错误。
把订阅转成分享链接后,节点怎么不再自动更新了?
剪贴板导入通常只生成当前节点的副本,不保留获取它的订阅地址。需要持续更新时,在「订阅分组设置」中保存原订阅 URL,并从该分组执行更新;手工修改分组内节点前,也要考虑下次更新可能覆盖这些修改。
可以靠转换格式让旧内核支持新参数吗?
不能。转换只能改变表达方式,不会增加内核能力。记录客户端与内核的实际版本,再核对目标协议、安全层和传输方式的支持情况;遇到未知字段时,优先更新兼容版本或获取服务端提供的兼容配置,不要随意删除关键参数。
实际操作的顺序可以固定为:确认获取到什么内容,选择对应导入入口,再核对协议参数与内核日志。把“获取失败”“格式不匹配”和“连接配置错误”分开处理,比不停更换编码方式更容易定位问题。