本文速览

订阅地址负责获取内容,base64 负责文本编码,分享链接描述单个节点,原生 JSON 描述内核运行配置。本文适合遇到“导入失败”“转换后少了规则”或“同一订阅在不同客户端结果不同”的用户:先辨认数据层级,再按入口导入,最后检查转换能否保留传输、TLS、DNS 与路由设置。

一、订阅地址、编码和节点配置不是同一层

“V2Ray 订阅”不是一种严格统一的文件格式。客户端先访问订阅 URL,再解析服务器返回的正文。常见返回内容是多行分享链接,或者把这些行整体做 base64 编码;也有服务直接返回 JSON。地址以 HTTPS 开头,只能说明获取方式,不能说明正文一定能被某个导入器识别。

对象常见特征包含范围导入入口
订阅 URLHTTPS 地址,可能带访问令牌远程内容的获取位置订阅分组设置
base64 订阅正文解码后通常是一行一个链接节点集合,不必含本地策略订阅更新解析器
分享链接vmess:// 或 vless://单个节点及其连接参数从剪贴板导入
原生 JSONinbounds、outbounds 等键入站、出站及可选 DNS、路由自定义配置入口

JSON 本身只是语法,不是配置类型。一个带有 add、id、net 的 VMess 分享对象,也能通过 JSON 语法检查,却不能直接当作完整 Xray 配置运行。反过来,把完整配置编码成 base64,也不会自动变成客户端支持的节点订阅。

二、base64 订阅:先解码,再按行解析

传统节点订阅常把多个分享链接用换行符连接,再对整段 UTF-8 文本编码。客户端拿到正文后,先还原文本,再逐行识别协议。VMess 还可能在单条链接内部再包一层 base64,因此“外层订阅解码成功”不等于“内层节点字段有效”。

  1. 取得正文:确认收到的是订阅内容,而不是登录页、访问限制说明或服务器错误页。
  2. 判断外层:如果正文已经以分享链接开头,先按纯文本处理,不要盲目重复解码。
  3. 解开编码:外层 base64 还原后,检查是否得到一行一个链接的文本。
  4. 解析节点:识别每行的协议,再检查服务器地址、端口、用户标识和传输参数。

标准 base64 常见字符包括 +、/,末尾可能带 =。有些来源使用 URL 安全变体中的 - 和 _,或者省略尾部填充。不同导入器的容错能力不同;不能仅凭“没有等号”判定订阅损坏,也不能把整段 base64 当 URL 百分号编码处理。

// 本地 JavaScript 示例:输入为已取得的多行分享链接文本。
// TextEncoder / TextDecoder 用于保留中文节点名称。
function encodeSubscription(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  for (const byte of bytes) {
    binary += String.fromCharCode(byte);
  }
  return btoa(binary);
}

function decodeSubscription(encoded) {
  let normalized = encoded.replace(/\s/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");
  normalized += "=".repeat((4 - normalized.length % 4) % 4);
  const binary = atob(normalized);
  const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

这段代码只转换文本,不会联网获取订阅,也不会验证节点是否可连接。解码失败时应先检查内容是否被截断、是否复制进了说明文字;解码成功后仍要交给支持对应协议的客户端解析。浏览器直接对中文调用 btoa() 可能报错,因此示例先转换为 UTF-8 字节。

三、VMess 与 VLESS 分享链接:逐项对应字段

常见的 vmess:// 分享形式是在协议前缀后拼接一个 base64 编码的 JSON 对象。下面是编码之前的对象,属于常见分享约定,不是完整内核配置。域名与 UUID 仅用于说明结构,不能直接作为可用节点。

{
  "v": "2",
  "ps": "示例 VMess WS",
  "add": "node.example.org",
  "port": "443",
  "id": "2d1e7e18-49f4-4ab7-8b63-c929d11c5e29",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "node.example.org",
  "path": "/proxy",
  "tls": "tls",
  "sni": "node.example.org"
}

v 是分享对象的格式标记,不是客户端版本;ps 是备注;add 和 port 是连接目标;net、host、path 描述传输层。这里的 aid 为零,不能据此推断 VLESS 也存在同名参数。不同分享实现可能省略字段,导入后应回到节点编辑页核对。

VLESS 分享链接常采用 URI 结构:用户标识放在 @ 之前,服务器和端口放在其后,查询参数描述传输与安全设置,# 后面是备注。下面与后文 JSON 使用同一组示例参数。

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=node.example.org&path=%2Fproxy&sni=node.example.org#Example-WS

结论:按字段转换,不按协议名替换

把 vmess:// 改成 vless:// 不能转换协议。只有服务端本身提供对应协议参数,才有生成另一种链接的依据;同一节点跨格式表达时,也要保留传输、安全层和认证字段。

四、原生 JSON:节点参数之外还有运行环境

原生 Xray 配置描述的是整个进程如何工作。入站决定本机应用从哪里接入,出站决定请求如何发往服务器,路由与 DNS 决定分流及解析方式。下面是用于字段对照的最小配置,采用 VLESS、WebSocket 与 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": "node.example.org",
            "port": 443,
            "users": [
              {
                "id": "2d1e7e18-49f4-4ab7-8b63-c929d11c5e29",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "node.example.org"
        },
        "wsSettings": {
          "path": "/proxy",
          "headers": {
            "Host": "node.example.org"
          }
        }
      }
    }
  ]
}
10808
示例本地 SOCKS 入站端口
443
示例远端 TLS 服务端口

这两个端口承担不同角色。10808 绑定本机回环地址,只是示例约定,不代表每台设备的实际设置;443 是远端监听端口,必须与服务端一致。若本机已有进程监听相同地址和端口,启动第二份配置可能失败。

五、v2rayN 与 v2rayNG:选择正确导入入口

客户端界面名称会随版本和界面语言调整。下面按常见简体中文菜单说明;操作前先分清剪贴板里是订阅 URL、单节点链接,还是完整 JSON。尤其不要把 HTTPS 订阅地址当成普通节点链接导入。

v2rayN:分组订阅与单节点分开导入

  1. 添加订阅组

    主界面「订阅分组」→「订阅分组设置」,在列表中选择「添加」,填写备注和订阅地址并保存。地址中的查询参数要完整保留。

  2. 更新订阅

    回到「订阅分组」菜单,选择更新当前或全部订阅;菜单如区分通过代理与不通过代理,按当前网络的实际可达性选择,再查看更新日志。

  3. 导入单节点

    复制完整的 vmess:// 或 vless:// 链接,在主窗口使用「服务器」→「从剪贴板导入批量 URL」,常见快捷键为 Ctrl+V。

  4. 核对连接项

    打开节点编辑窗口,核对地址、端口、UUID、传输类型、路径与 TLS 服务器名称。导入成功只表示解析完成,不代表服务端可连接。

v2rayNG:订阅分组与剪贴板入口

六、互转方案:按保留范围选择

“互转成功”至少要分为三个标准:文本可解码、客户端可导入、连接行为符合预期。前两项通过,仍可能丢失路由、DNS、指纹或传输扩展参数。先确定迁移目标,通常比先找一个转换按钮更省排查时间。

分享链接迁移节点

推荐

通过客户端提供的分享或复制链接功能导出,再在目标客户端导入。完成后逐项核对传输与 TLS 参数;本地路由和 DNS 单独迁移。

适合:跨设备迁移单个节点、整理少量连接

订阅地址维护列表

在目标客户端重新添加订阅地址,交由其解析和更新。把正文转成静态链接列表只得到某一时刻的快照,不会自动保留远端刷新机制。

适合:节点经常调整、需要持续更新的分组

原生 JSON 保留策略

在兼容内核之间迁移配置,并逐项检查文件引用、端口、系统权限与字段支持情况。导入自定义配置后,部分客户端界面选项未必会作用于该配置。

适合:包含多个出站、自定义 DNS 或复杂路由

迁移后先检查日志是否出现配置解析或监听错误,再选择一个节点验证实际连接。桌面端还要检查系统代理或应用内代理是否指向真实入站;Android 端则确认连接服务已经启动,并按系统提示授予 VPN 接口权限。测速有结果和浏览器流量经过代理,是两个不同的验证动作。

七、导入与转换常见问答

订阅地址能打开,为什么更新后是零个节点?

先检查响应正文是否为 HTML 页面、错误信息或客户端不支持的格式。浏览器能访问 URL,不代表返回的是节点列表。确认令牌未失效,再查看客户端更新日志中的解析错误。

base64 解码后还是 vmess 开头,还要继续解码吗?

外层订阅已经解开。单行 vmess:// 后的内容在常见格式下还有一层编码,但应只解析协议前缀后的载荷,不要把整个多行列表再次整体解码。正常导入时由客户端完成这一层处理。

JSON 检查通过,为什么内核还是不能启动?

语法正确不等于字段合法。先区分 VMess 分享对象与完整配置,再检查内核是否支持协议和字段;若日志提示监听失败,核对本地端口是否被占用,而不是反复更换订阅编码。

转换成链接后,原来的分流规则怎么没了?

单节点链接通常只携带连接参数。需要恢复分流时,在目标客户端重建路由和 DNS,或者使用兼容的完整配置迁移方式。不要把缺少本地策略误认为节点认证参数丢失。

导入成功,但提示 TLS 或握手错误怎么办?

打开节点编辑页,对照服务端资料检查端口、传输类型、SNI、WebSocket Host 和路径,确认设备时间正常。不要用关闭证书验证来代替字段修正;若原始链接也失败,应继续排查服务端状态与网络连通性。