V2Ray 订阅链接格式详解:Base64 订阅、原生 JSON 与分享链接互相转换

科普常见订阅格式的结构与适用客户端,说明 Base64 订阅如何解码成逐行分享链接、分享链接与原生 JSON 配置怎样对应,以及导入失败的格式原因。

本文速览

订阅地址负责获取内容,Base64 负责文本编码,分享链接描述单个节点,原生 JSON 描述内核配置。本文适合遇到“订阅为空”“JSON 无法导入”或需要迁移节点的用户:先识别响应格式,再在本地解码,最后核对协议、传输与 TLS 字段。转换只改变表达方式,不会补出缺失的服务端参数,也不保证不同内核之间的功能等价。

一、订阅地址、分享链接与原生 JSON 的区别

“V2Ray 订阅”不是一种统一的文件扩展名。客户端访问一个 HTTPS 地址后,可能得到 Base64 文本、逐行分享链接、JSON,也可能得到登录页面。判断格式要看实际响应正文,不能只凭网址是否以 .txt 或 .json 结尾。

客户端可识别的订阅地址

推荐

由 v2rayN、v2rayNG 或 v2flyNG 拉取节点列表。前提是服务商提供的响应格式与当前客户端兼容;更新时仍可保留分组关系,不必每次手工复制节点。

适合:日常更新、多设备分别维护订阅分组

逐行分享链接

每行描述一个节点,常见前缀为 vmess://、vless://。适合单节点排错;批量导入后通常只是一次快照,不会自动继承原订阅更新关系。

适合:离线迁移、核对某个节点的字段

内核原生 JSON

可能同时包含入站、出站、DNS 与路由规则。它不是通用节点列表,通常需要使用客户端的自定义配置入口,并匹配所选内核的配置结构。

适合:保留明确的 DNS、路由和多出站设计

客户端与内核也要分开看:v2rayN 是桌面客户端;v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核。能导入某种链接,只代表客户端识别了文本,不代表当前内核支持链接声明的全部能力。尤其涉及 REALITY 或特定流控时,应核对内核,而不是反复做 Base64 编解码。

二、先识别订阅响应,再决定是否解码

在受信任的本地工具中查看响应时,先去掉开头的空白,观察第一段内容。订阅地址里的令牌通常具有账户访问意义,不要把完整网址、响应正文或二维码发给在线转换站点。浏览器若显示验证码、登录表单或错误页面,应先解决访问问题。

看到的内容可能的格式下一步
vmess:// 或 vless://明文分享链接列表按行导入,不要再对整个正文解码
大段字母、数字及少量符号可能是 Base64 编码列表本地解码一次,再观察是否出现协议前缀
{ 或 [可能是 JSON先解析结构,区分接口响应、节点对象与完整配置
<!DOCTYPE html> 或 <html网页或访问拦截响应检查地址、登录状态与订阅有效期

HTTP 状态码 200 只说明请求得到正常响应,不保证正文是节点。即使正文是合法 JSON,里面也可能只有错误码与提示信息。先判断内容,再选择导入入口,比不断切换代理或修改端口更有效。

三、Base64 订阅怎样还原成逐行分享链接

常见的传统订阅生成流程是:把多个分享链接用换行连接,再对整段 UTF-8 文本做 Base64 编码。解码时反向执行即可。需要留意标准 Base64 的 +、/ 与 URL 安全变体的 -、_,以及末尾可能省略的 = 填充。

3 → 4
每 3 字节编码为 4 个 Base64 字符,不足时填充
443
本文示例的远端 TLS 端口
10808
常见本地代理端口示例,以客户端实际监听为准

下面是可供本地检查的原生 JavaScript 函数。代码只处理传入字符串,不发起网络请求。可在自行创建的离线 HTML 页面中运行;不要把真实订阅粘贴到不可信网页的控制台。UTF-8 解码很重要,否则带中文的节点名称可能乱码。

function base64ToText(source) {
  const normalized = source
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized)) {
    throw new Error("内容不符合 Base64 字符规则");
  }

  const body = normalized.replace(/=+$/, "");
  if (body.length % 4 === 1) {
    throw new Error("Base64 长度异常,检查是否复制完整");
  }

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

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

// 本地自检,结果为 true。
console.log(base64ToText(textToBase64("订阅格式测试")) === "订阅格式测试");
  1. 将订阅响应正文传给 base64ToText,不是把 HTTPS 订阅地址传进去。
  2. 用换行拆分解码结果,去除空行与行首、行尾空白;保留每个链接内部的完整字符。
  3. 检查每一行的协议前缀,先选一个节点测试导入,再批量处理。
  4. 需要重新生成传统 Base64 列表时,用 textToBase64(links.join("\n")) 编码逐行链接文本;这不会自动生成可访问的订阅网址。

外层列表解码一次后,vmess:// 后面仍可能是一段 Base64,这是单节点自身的编码结构,不是解码失败。不要对整个结果机械地反复解码;应先按协议分支处理。

四、VMess 与 VLESS 分享链接怎样对应 JSON 字段

常见 VMess 分享格式是 vmess:// 加 Base64 编码的节点 JSON,常见键包括 add、port、id、net、host、path 与 tls。它是分享格式,不是可直接交给内核的完整配置;其中 v 表示分享格式版本,不是内核版本。

VLESS 分享链接通常把用户标识、地址、端口放在 URI 主体,把传输参数放在查询串。下面使用保留示例域名和演示 UUID,仅用于展示字段对应,不能作为实际节点连接。

vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=edge.example.com#TLS-demo
分享信息常见原生配置位置检查重点
地址与端口settings.vnext[].address / port远端端口不是本地监听端口
用户 UUIDsettings.vnext[].users[].id完整保留,不把备注当作用户标识
type=tcpstreamSettings.network采用当前内核支持的传输名称
security=tlsstreamSettings.security与协议认证、传输类型分别核对
snitlsSettings.serverName与服务端证书及配置要求匹配
WebSocket 的 host / pathwsSettings.headers.Host / path不能直接用 SNI 替代 Host

上述 VLESS 示例可对应为下面的 Xray 出站片段。它没有入站、DNS 与路由,不是完整可运行配置。复制到完整配置时应放入合适的 outbounds 数组位置,并按当前内核文档核对字段。

{
  "tag": "proxy",
  "protocol": "vless",
  "settings": {
    "vnext": [
      {
        "address": "node.example.com",
        "port": 443,
        "users": [
          {
            "id": "00000000-0000-4000-8000-000000000001",
            "encryption": "none"
          }
        ]
      }
    ]
  },
  "streamSettings": {
    "network": "tcp",
    "security": "tls",
    "tlsSettings": {
      "serverName": "edge.example.com",
      "allowInsecure": false
    }
  }
}

五、原生 JSON 为什么不能总是无损转回订阅

单个分享链接主要表达一个远端连接。完整原生 JSON 还可能包含多个出站、规则匹配、DNS 服务器、流量嗅探及本地监听。即使能从某个出站提取出一条 VLESS 链接,也不能靠这条链接恢复全部路由策略。因此“JSON 转订阅”必须先说明是提取节点,还是保留整个运行环境。

转换方案:区分节点迁移与完整配置迁移

只迁移节点
  • 从 outbounds 找到实际代理出站,而不是直连或阻断出站。
  • 提取协议、地址、端口、认证、传输和 TLS 参数。
  • 生成当前客户端能识别的分享链接,逐个试导入。
  • 在目标客户端单独配置 DNS、系统代理与分流规则。
保留完整配置
  • 备份原 JSON,记录对应内核与实际版本。
  • 检查文件路径、监听地址和端口占用。
  • 使用客户端提供的自定义配置入口,不当作普通订阅导入。
  • 启动后检查日志,并确认 DNS 与路由是否按预期执行。

结论:分享链接便于交换节点;原生 JSON 适合保留配置结构。外层重新编码不会弥补两者的信息差。

同样,Xray 与 V2Fly 的 JSON 也不是只改文件名就能通用。特定协议扩展、传输字段与 DNS 选项存在差异。把不支持的字段删掉,可能让配置通过解析,却改变连接行为;应先确认服务端要求,再决定是否迁移。

六、在 v2rayN 与安卓客户端中选择正确入口

界面文字会随版本变化,下面按常见中文菜单说明操作目的;若本机名称不同,找“订阅分组”“剪贴板导入”或“自定义配置”对应功能。不要把订阅网址粘贴到只接受单节点分享链接的编辑框,也不要把一整份 JSON 填进服务器地址栏。

  1. v2rayN 添加长期订阅:进入「订阅分组」→「订阅分组设置」,新增分组并填写订阅地址。保存后在订阅菜单选择「更新订阅(不通过代理)」或相应更新项;网络确实需要代理时,再选择「更新订阅(通过代理)」。
  2. v2rayN 导入一次性链接:复制完整的逐行分享链接,在「服务器」菜单选择「从剪贴板导入批量 URL」。先检查导入后的传输类型、TLS 与 SNI,再设为活动服务器。
  3. v2rayNG 更新订阅:进入「订阅分组设置」,新建分组、填写 URL 并保存,然后返回列表执行「更新订阅」。剪贴板节点应使用添加菜单中的「从剪贴板导入」,两种入口不要混用。
  4. v2flyNG 检查兼容性:使用其订阅或分享链接导入入口前,先确认节点配置适用于 V2Fly 内核。遇到需要 Xray 专有能力的节点,应向服务方获取适配配置,不能靠编码转换解决。

七、订阅转换与导入失败的常见问题

解码后还是 vmess:// 加一长串,是不是没解完?

外层订阅列表已解码完成。先按换行拆成节点,再单独取某条 vmess:// 后的载荷解码并解析 JSON。不要把整个列表再次送进 Base64 解码器,也不要把 VMess 分享对象直接当作内核配置。

JSON 能打开,客户端为什么显示零个节点?

先检查顶层键。如果是 inbounds、outbounds,它可能是完整内核配置,应使用自定义配置入口;如果是错误码与说明,应先修复订阅访问。JSON 语法正确和订阅格式受支持是两件事。

复制后导入失败,应该先检查哪里?

检查链接是否被聊天工具截断、查询串中的 & 是否被替换成字面量 HTML 实体、是否混入全角冒号或引号。先用一条完整链接测试,确认节点详情正常,再导入其余内容。

节点导入成功却连不上,还要换一种订阅格式吗?

先核对地址、443 等实际服务端端口、UUID、传输路径、SNI 与内核支持情况,再看连接日志。10808 这类本地监听端口不能填到远端端口位置。字段已正确导入时,重新编码通常不会修复连接故障。

能把订阅发给在线工具,让它转换成 JSON 吗?

优先使用本地工具和客户端导出功能。订阅 URL 与节点认证信息都应视作敏感数据;如果已泄露,应在服务方管理页重置订阅令牌,并按其规则更换节点凭据,之后更新各端保存的地址。

最终检查顺序可以压缩为四步:看响应正文,辨认格式层级,核对节点字段,验证内核运行。需要了解 TLS、出站与路由术语时,可查阅术语手册;已经完成导入但仍无法联网时,再按技术参考检查日志与网络设置。

V2Ray客户端下载