V2Ray 订阅链接格式详解:base64、原生 JSON 与分享链接如何互转

科普常见订阅内容的三种形态及各客户端的识别差异,说明 base64 列表、原生 JSON 与 vmess:// 分享链接之间的转换思路。

本文速览

订阅地址是入口,base64 是编码,分享链接描述单个服务器,原生 JSON 则可能包含整套运行配置。本文适合遇到“更新成功却没有服务器”“JSON 无法导入”或需要迁移客户端的用户:先识别响应内容,再选择导入入口,最后判断哪些字段可以转换、哪些设置必须单独保留。

一、先分清订阅地址、响应内容与节点协议

通常所说的订阅链接,是一个通过 HTTPS 获取内容的地址。客户端请求它,拿到服务器列表或配置文本,再尝试解析。地址里可能带有访问令牌;它本身不是 VMess 或 VLESS 协议,也不能仅凭网址后缀判断返回格式。同一个入口还可能按请求参数或客户端标识返回不同内容。

常见列表的基本单位是分享链接,例如以 vmess:// 或 vless:// 开头的文本。多条链接按行排列后,可以直接返回,也可以整体做一次 base64 编码。另一类响应则是 JSON,但“能被 JSON 解析器打开”只说明语法成立,不代表客户端知道该把它当作服务器列表还是完整配置。

形态识别线索通常包含什么应选入口
明文分享列表每行以协议前缀开头多个服务器的连接参数分享链接或剪贴板导入
base64 列表解码后得到多行分享链接与明文列表相同的内容兼容该格式的订阅更新
原生配置 JSON常见顶层键为 inbounds、outbounds入站、出站、DNS、路由等设置自定义配置或配置文件导入

二、base64 只改变表示方式,不改变协议能力

base64 把字节表示为便于传递的文本,并不提供保密性。一个中文备注需要先转成 UTF-8 字节,再做 base64;反向处理则先还原字节,再按 UTF-8 解码。直接对包含中文的字符串调用浏览器 btoa(),可能报错或产生错误结果。

3 → 4
每 3 字节编码为 4 个字符,末组可带填充
2 层
外层列表与内层 VMess 内容可能分别编码
443
下文 TLS 示例端口,不是格式识别条件

标准 base64 常见字符包括 +、/,末尾可能有 =。URL 安全变体用 -、_ 替换前两者,并可能省略填充。部分客户端会兼容这些差异,但不能假定所有导入器都会自动修复空格、截断或多余引号。

结论:先解一层,再决定导入方式

解码结果若是多行分享链接,就使用链接列表入口;若是带入站、出站和路由的对象,就核对自定义配置入口。编码层数不是协议兼容性的证据。

三、VMess 分享 JSON 与原生配置不是同一种结构

经典的 VMess 分享链接通常使用“vmess:// 加 base64 编码 JSON”的形式。下面是这种分享对象的教学示例,不是可连接的服务器,也不能直接作为内核运行配置。域名使用保留的示例域,端口 443 仅用于说明 TLS 场景。

{
  "v": "2",
  "ps": "格式演示",
  "add": "example.invalid",
  "port": "443",
  "id": "123e4567-e89b-42d3-a456-426614174000",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.invalid",
  "path": "/edge",
  "tls": "tls",
  "sni": "example.invalid"
}

这里的 v 是分享格式标记,不是客户端版本;ps 是备注;add、port 和 id 对应地址、端口和用户标识。net 描述传输方式,host 与 path 在这个示例中服务于 WebSocket,sni 对应 TLS 服务器名称。它们有不同职责,不能因为值相同就视作同一个字段。

分享对象字段原生配置中的典型位置转换注意点
add、portoutbounds[].settings.vnext[] 中的地址与端口原生端口通常应为数字,不能只复制字符串类型
id、scyVMess 出站用户项中的 id、security字段名并不完全相同,需按内核配置规范映射
net、pathstreamSettings 及对应传输设置只有匹配的传输类型才解释相应字段
tls、snistreamSettings.security 与 TLS 设置协议加密参数与 TLS 设置属于不同层

原生 JSON 可能同时定义多个出站,并由路由规则选择出口。导出其中一个节点时,通常不会顺带保存 DNS、分流规则、入站监听地址或出站链路。因此,“原生 JSON 转分享链接”往往是抽取连接参数,不是完整配置的可逆压缩。

四、本地互转:先处理文本,再处理配置语义

“分享链接列表转 base64”和“base64 还原列表”只是编码操作,可以在本地完成。下面的 JavaScript 仅定义文本处理函数,不发送网络请求。可在自己创建的本地空白页面开发者工具中运行;不要在陌生网站的控制台粘贴真实订阅内容,也不要执行来源不明的转换脚本。

function encodeUtf8Base64(text) {
  const bytes = new TextEncoder().encode(text);
  const binary = Array.from(bytes, byte =>
    String.fromCharCode(byte)
  ).join("");
  return btoa(binary);
}

function decodeUtf8Base64(input) {
  let text = input.trim()
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(text)) {
    throw new Error("内容不是预期的 base64 文本");
  }

  if (text.length % 4 === 1) {
    throw new Error("长度异常,请检查复制是否完整");
  }

  text += "=".repeat((4 - text.length % 4) % 4);
  const binary = atob(text);
  const bytes = Uint8Array.from(binary, char =>
    char.charCodeAt(0)
  );
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

function packShareList(links) {
  return encodeUtf8Base64(links.join("\n"));
}

function makeClassicVmessLink(shareObject) {
  return "vmess://" + encodeUtf8Base64(JSON.stringify(shareObject));
}

// 只验证 UTF-8 往返,不使用真实订阅凭据。
const sample = "中文备注\n第二行";
console.assert(
  decodeUtf8Base64(encodeUtf8Base64(sample)) === sample
);
  1. 还原列表:对响应文本调用 decodeUtf8Base64(),检查输出是否确实为逐行分享链接。该函数不会自动判断协议或修复损坏内容。
  2. 包装列表:将每条完整 URI 放入数组,交给 packShareList()。换行是条目分隔符,不能把多条 URI 无分隔拼接。
  3. 生成 VMess:只有输入对象已经符合经典 VMess 分享字段时,才使用 makeClassicVmessLink()。它不会把任意原生配置自动变成正确节点。
  4. 校验结果:先在客户端中导入为测试条目,逐项核对地址、端口、UUID、传输、TLS 与服务器名称,再测试连接。

真正的“原生配置转分享链接”还需要语义转换器:确定要导出哪个出站,识别协议与传输,映射字段,再判断目标分享格式能否表达全部参数。遇到无法表示的字段,应停止转换或记录缺失项,不能静默丢掉后宣称转换成功。

五、三款客户端如何选择导入入口

先按用途选择:需要持续更新的一组服务器用订阅;临时迁移一个节点用分享链接;需要完整控制 DNS、路由与出站的配置再考虑原生 JSON。客户端界面负责导入与管理,内核负责运行协议,两者的兼容范围要分别确认。

订阅入口

推荐

保存订阅地址,由客户端定期或手动获取服务器列表。更新方便,但服务端返回的格式必须能被当前导入器识别。

适合:日常管理会持续变更的服务器列表。

分享链接入口

从剪贴板导入单条或多条 URI,适合核对参数。它通常不会自动保留与原订阅的更新关系。

适合:临时测试、单节点迁移与格式排障。

自定义配置入口

按客户端提供的自定义配置功能加载原生 JSON。配置必须匹配实际内核,路由及 DNS 的接管方式也应单独检查。

适合:已有完整配置、需要保留高级出站与路由的用户。

v2rayN 用于桌面端;v2rayNG 是使用 Xray 内核的安卓客户端;v2flyNG 是使用 v2fly 内核的安卓客户端。VMess 分享链接是常见交换方式,但具体传输及扩展参数仍受版本影响。特别是面向 Xray 的扩展配置,不能默认由 v2fly 内核直接执行。

  1. 保留原配置

    先保留现有可用条目和原始响应。排障使用独立订阅分组,不要先清空所有服务器。

  2. 桌面加订阅

    v2rayN 常见路径为「订阅分组」→「订阅分组设置」→「添加」:填写备注与地址,保存后从「订阅分组」菜单执行更新。跨平台界面与不同版本的按钮文字可能略有差异。

  3. 安卓加订阅

    v2rayNG 常见路径为右上角菜单「⋮」→「订阅分组设置」→「+」;保存后回到主界面,从「⋮」→「更新订阅」获取条目。不要把订阅网址当成服务器地址填写。

  4. 单条做对照

    在 v2rayN 的「服务器」菜单中选择从剪贴板导入;v2rayNG 常见入口为主界面「+」→「从剪贴板导入」。用同一条分享链接测试,可区分订阅获取故障与节点解析故障。

  5. 核对内核

    在 v2flyNG 中使用其订阅设置或剪贴板导入入口,并核对 v2fly 对相关参数的支持。原生 JSON 应走该版本提供的自定义配置入口,而不是直接粘贴到订阅地址栏。

六、导入失败时,按获取、解析、运行分层排查

更新提示完成,只能说明某个更新流程走到了结束,不足以证明所有条目都解析成功。反过来,条目已经出现在列表中,也不代表传输与 TLS 参数完全正确。保留错误发生的阶段,比反复修改编码更有效。

现象优先检查下一步
订阅请求失败地址是否完整,令牌是否失效,是否返回 401 或 403确认服务提供方授权状态,不要尝试用转码绕过权限
返回 200 但没有条目响应是否为登录页、错误 JSON 或不兼容格式识别正文类型,再换到正确导入入口
base64 解码报错文本是否被截断,是否混入引号,变体是否受支持重新复制原文,检查长度与实际响应内容
JSON 能解析却不能导入是否把分享对象、配置文件或接口错误对象混为一谈检查顶层键与客户端期待的结构
条目存在但连接失败端口、UUID、传输、TLS、SNI 和路径按原配置逐项对照,再检查网络可达性
把原生 JSON 整体做 base64,就能变成通用订阅吗?

不能。编码不会改变数据结构。解码后仍是一份原生配置,客户端若只接受分享链接列表,就仍然无法按列表解析。应使用支持该配置的入口,或有选择地抽取可表达的节点参数。

导入分享链接后,为什么原来的分流规则没有了?

分享链接通常描述单个节点,不携带完整路由体系。客户端已有的分流设置和原生配置中的规则也可能属于不同管理层。迁移前应分别保存 DNS、路由、入站及其他出站配置。

订阅更新后,手动修改的参数为什么被恢复?

订阅条目往往以远端内容为准,更新时可能重建或覆盖本地条目。需要长期保留的修改,应另存为独立配置,并明确它不会自动跟随原订阅变化。

结论:先保证字段完整,再考虑转换便利

优先使用服务提供方明确支持的订阅格式。必须迁移时,先用一个节点验证转换结果,并单独保存路由与 DNS;确认可用后再批量处理。

下载v2rayN查看平台与安装包