订阅地址是获取内容的入口,Base64 是编码方式,分享链接描述单条连接,原生 JSON 则可能包含整套内核运行配置。本文适合需要迁移订阅、排查导入失败或保留自定义配置的用户:先识别输入,再按字段转换,最后在客户端检查连接、传输与路由是否完整。
一、先区分地址、编码与配置内容
“V2Ray 订阅格式”不是一个统一的文件规范。常见订阅接口通过 HTTPS 返回一段文本;这段文本可能是多条分享链接,也可能是它们整体经过 Base64 编码后的结果。订阅 URL 本身并不等于节点配置,客户端还需要请求地址并解析响应。
文件名也不能证明内容格式。以 .json 结尾的地址可能返回错误页;没有扩展名的地址也可能返回合法 JSON。应先看响应内容,再决定使用“订阅更新”“从剪贴板导入”还是“自定义配置导入”。
服务方提供的兼容订阅
推荐对需要持续更新节点的用户,优先使用明确支持目标客户端的订阅。常见内容是 Base64 包装的分享链接列表,但应以服务方说明和实际响应为准。
适合:日常更新、多设备分别导入、节点地址变更
单条或多条分享链接
vmess://、vless:// 等链接便于迁移单条连接。多条链接通常按行排列;链接本身不提供自动更新关系。
适合:临时测试、单节点迁移、核对连接字段
原生 JSON 配置
完整配置可以描述入站、出站、DNS 和路由。JSON 只是语法容器,实际字段必须符合目标内核及其版本,不能仅凭能解析就认定可运行。
适合:固定路由、自定义 DNS、完整运行环境迁移
二、Base64 订阅如何识别与解码
传统链接列表订阅常见的处理过程是:先把每条分享链接放在独立一行,再将整个文本转换为 UTF-8 字节,最后进行 Base64 编码。解码后应出现可辨认的协议前缀,而不是直接得到一份完整的内核配置。
以下 JavaScript 只演示本地字符串处理。它接受标准 Base64,也兼容常见的 URL 安全字母表;移除的是编码文本中的空白,不是分享链接内部的字符。遇到长度异常或非法字节应停止检查,不要靠反复解码来“修复”。
function decodeSubscription(encoded) {
const text = encoded.trim()
.replace(/\s/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(text) ||
text.length % 4 === 1) {
throw new Error("Base64 文本格式异常");
}
const padded = text + "=".repeat((4 - text.length % 4) % 4);
const bytes = Uint8Array.from(atob(padded), ch => ch.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeSubscription(linkText) {
const bytes = new TextEncoder().encode(linkText);
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
- 解码后出现
vmess://或vless://:按行检查分享链接。 - 原始内容以
{或[开头:先判断是不是 JSON,不要先做 Base64 解码。 - 出现 HTML 标签、登录提示或接口错误:检查订阅授权、到期状态和网络请求结果。
- 外层解码完成后,某条
vmess://的载荷仍可能是 Base64;这是链接自身的一层编码,不是外层订阅解码失败。
三、分享链接转 JSON:按语义映射字段
链接转换不是替换前缀。常见 VMess 分享格式把一段 JSON 编码后放到 vmess:// 后面;VLESS 分享链接常采用 URI 结构,由用户标识、主机、端口、查询参数和备注组成。不同客户端对扩展参数的支持可能不同。
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.com#format-demo
这是一条用于说明字段的虚构连接,example.com 是文档示例域名,不能用于实际连接。这里的 encryption=none 对应 VLESS 用户层设置,不代表关闭 TLS;传输安全由 security=tls 表达。
| 链接信息 | 常见 JSON 对应位置 | 核对重点 |
|---|---|---|
| 主机与端口 | settings.vnext[].address、port | 端口应为数字,域名不能误填为备注 |
| 用户标识 | settings.vnext[].users[].id | 完整保留 UUID,不包含 URI 分隔符 |
encryption=none | users[].encryption | 此处是 VLESS 字段,不能套用到 VMess |
security=tls | streamSettings.security | 不要与 VMess 用户的加密设置混淆 |
sni=example.com | tlsSettings.serverName | 保留服务端要求的 TLS 名称 |
type=tcp | streamSettings.network | 传输名称及可接受别名需核对内核版本 |
以下是面向支持这些字段的 Xray 内核的结构示例。10808 只绑定回环地址,443 是远端端口,两者不能互换。此处使用传统 tcp 写法;不同内核版本的传输命名与兼容别名应以其文档为准。
{
"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": "7c9c1f0b-4bd8-4b44-8eb2-3eb2ac702783",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "example.com"
}
}
}
]
}
四、JSON 转分享链接:哪些内容会丢失
从完整配置导出分享链接时,转换器通常只提取一个代理出站。一个 JSON 可以包含多个 outbounds,其中还可能有直连或阻断出站。转换前应先选择目标代理的 tag,不能把数组中的第一项一概当成节点。
转换方案:连接迁移与完整配置迁移分开处理
只迁移连接
- 从目标出站提取协议、服务器、端口与身份字段。
- 保留 TLS 名称、传输路径和服务端要求的流控。
- 生成分享链接,在目标客户端重新配置本地代理与路由。
保留完整行为
- 保留原生 JSON,并确认目标内核可读取。
- 核对入站端口、DNS、路由规则以及外部数据文件。
- 使用客户端的自定义配置入口,检查其是否改写配置。
分享链接适合传递连接参数;完整运行行为需要配置文件、依赖资源与内核能力共同保留。
routing.rules、dns、本地监听地址和分应用设置通常不属于普通节点分享链接。把 JSON 转成链接,再从链接导回 JSON,得到的配置不一定与原文件等价,即使连接成功也不能证明分流结果一致。
- 先保存原 JSON 副本,记录要迁移的出站
tag。 - 逐项比较服务端地址、端口、身份、传输、TLS 与流控,不只比较节点名称。
- 备注和查询参数按 URI 规则编码。特别留意路径中的
?、&、#,避免被误当成链接分隔符。 - 如果转换器提示不支持字段,停止自动迁移并手动核对;不要静默删除后继续使用。
五、分享链接重新打包为订阅:更新关系不会自动恢复
将多条分享链接按行连接,再对整体文本进行 Base64 编码,可以得到传统链接列表订阅的内容。但这只是一个快照。要让客户端定期获取它,还需要一个由自己或可信服务方管理、可持续访问的订阅地址。
- 输入整理:每行只保留一条完整链接,删除空行,不把网页标题或说明文字一起编码。
- 编码处理:统一使用 UTF-8,检查中文备注编码;不要直接用只接受单字节字符的方式处理中文字符串。
- 输出检查:将编码结果再解码一次,确认链接数量、逐行顺序和参数内容保持一致。
- 更新策略:节点地址或凭据变化后,静态快照不会随原订阅变化;需要重新生成并发布内容。
原生 JSON 也不能通过“整体 Base64 一次”就变成各客户端通用的订阅。编码不会改变内部数据结构。目标入口如果只接受分享链接列表,收到解码后的完整 JSON 仍可能导入失败。
六、在 v2rayN 与 v2rayNG 中核对转换结果
先在独立测试分组导入,避免订阅更新覆盖现有手动配置。下面给出常见入口名称;不同版本的排列与文字可能有调整,操作时以当前界面为准,不要把完整 JSON 填进订阅 URL 栏。
- v2rayN 订阅:打开「订阅分组」→「订阅分组设置」,新增测试分组并填入可信的订阅 URL,再使用该分组的更新命令。
- v2rayN 分享链接:复制链接,在主界面使用「从剪贴板导入批量 URL」,检查新增条目所在分组。
- v2rayNG 分享链接:点右上角「+」→「从剪贴板导入」,随后编辑新条目,核对服务器、端口和传输参数。
- v2rayNG 订阅:在菜单「订阅分组设置」中添加地址,返回后执行「更新订阅」,确认更新的是测试分组。
- 原生 JSON:使用当前版本提供的自定义配置文件导入入口,先检查日志中的配置解析结果,再启动连接。
启动后分三层判断:第一层是内核能否解析并监听本地端口;第二层是远端握手能否完成;第三层是应用流量是否进入代理并命中预期路由。列表出现节点只证明解析器保存了数据,不能替代后两层检查。
解码后能看到链接,为什么还是导入失败?
检查是否把多条链接粘成一行,或把引号、逗号一起复制进去。先只导入其中一条,再检查协议和传输是否受目标内核支持;单条失败时,继续重编码整个列表没有帮助。
导入成功,但一启动就提示端口占用怎么办?
核对自定义 JSON 的 inbounds[].port。如果示例中的 10808 已被其他进程占用,应停止冲突进程或更换端口,并同步调整应用代理地址。远端 443 不需要因此修改。
转换后 TLS 握手失败,要关闭证书验证吗?
先比较服务器地址、serverName、系统时间和传输设置。检查转换器是否遗漏 SNI 或误改 TLS 类型;应修复字段,不要用关闭证书验证来掩盖不一致。
为什么节点能连接,国内外分流却变了?
分享链接通常没有携带原来的 routing 和 dns。在目标客户端重新选择路由配置,检查规则顺序与数据文件;如需复现原配置,应迁移完整 JSON 并核对内核兼容性。
更新订阅后,手动修好的参数又被改回去了?
订阅管理的条目可能在更新时重建。先把需要保留的配置复制到独立的手动分组,再向服务方核对原始订阅参数。不要把订阅生成项当成长期保存本地修改的位置。
最终应保存三样内容:原始输入的安全副本、转换时采用的字段映射、目标客户端中的核对结果。后续出错时,可以明确区分是订阅响应变化、转换丢字段,还是本地路由与端口设置改变。