订阅地址负责获取内容,base64 负责文本编码,分享链接描述单个节点,原生 JSON 描述内核运行配置。本文适合遇到“导入失败”“转换后少了规则”或“同一订阅在不同客户端结果不同”的用户:先辨认数据层级,再按入口导入,最后检查转换能否保留传输、TLS、DNS 与路由设置。
一、订阅地址、编码和节点配置不是同一层
“V2Ray 订阅”不是一种严格统一的文件格式。客户端先访问订阅 URL,再解析服务器返回的正文。常见返回内容是多行分享链接,或者把这些行整体做 base64 编码;也有服务直接返回 JSON。地址以 HTTPS 开头,只能说明获取方式,不能说明正文一定能被某个导入器识别。
| 对象 | 常见特征 | 包含范围 | 导入入口 |
|---|---|---|---|
| 订阅 URL | HTTPS 地址,可能带访问令牌 | 远程内容的获取位置 | 订阅分组设置 |
| base64 订阅正文 | 解码后通常是一行一个链接 | 节点集合,不必含本地策略 | 订阅更新解析器 |
| 分享链接 | vmess:// 或 vless:// | 单个节点及其连接参数 | 从剪贴板导入 |
| 原生 JSON | inbounds、outbounds 等键 | 入站、出站及可选 DNS、路由 | 自定义配置入口 |
JSON 本身只是语法,不是配置类型。一个带有 add、id、net 的 VMess 分享对象,也能通过 JSON 语法检查,却不能直接当作完整 Xray 配置运行。反过来,把完整配置编码成 base64,也不会自动变成客户端支持的节点订阅。
二、base64 订阅:先解码,再按行解析
传统节点订阅常把多个分享链接用换行符连接,再对整段 UTF-8 文本编码。客户端拿到正文后,先还原文本,再逐行识别协议。VMess 还可能在单条链接内部再包一层 base64,因此“外层订阅解码成功”不等于“内层节点字段有效”。
- 取得正文:确认收到的是订阅内容,而不是登录页、访问限制说明或服务器错误页。
- 判断外层:如果正文已经以分享链接开头,先按纯文本处理,不要盲目重复解码。
- 解开编码:外层 base64 还原后,检查是否得到一行一个链接的文本。
- 解析节点:识别每行的协议,再检查服务器地址、端口、用户标识和传输参数。
标准 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
security=tls表示传输安全层使用 TLS;encryption=none是 VLESS 参数,两者不是互相否定的设置。type=ws对应 WebSocket;path=%2Fproxy解码后为/proxy。host是 WebSocket 请求头中的主机信息,sni用于 TLS 服务器名称;它们可能相同,但不能互相随意替代。- IPv6 地址在 URI 中需要方括号;备注含空格、中文或特殊符号时,应按 URI 规则编码。
结论:按字段转换,不按协议名替换
把 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 绑定本机回环地址,只是示例约定,不代表每台设备的实际设置;443 是远端监听端口,必须与服务端一致。若本机已有进程监听相同地址和端口,启动第二份配置可能失败。
- 链接转 JSON:将节点参数映射到一个出站,再明确补齐入站、DNS 和路由;链接本身通常没有这些本地设置。
- JSON 转链接:从可表达的节点出站提取参数;多个出站通常要分别处理,不能默认压成一个节点。
- 策略保留:
routing、dns、入站监听及日志设置通常不会随单节点分享链接迁移。 - 内核兼容:Xray 与 V2Fly 的字段及协议能力存在差异;v2rayNG 使用 Xray,v2flyNG 使用 V2Fly,不能仅因两者都接受 JSON 就认定配置通用。
五、v2rayN 与 v2rayNG:选择正确导入入口
客户端界面名称会随版本和界面语言调整。下面按常见简体中文菜单说明;操作前先分清剪贴板里是订阅 URL、单节点链接,还是完整 JSON。尤其不要把 HTTPS 订阅地址当成普通节点链接导入。
v2rayN:分组订阅与单节点分开导入
-
添加订阅组
主界面「订阅分组」→「订阅分组设置」,在列表中选择「添加」,填写备注和订阅地址并保存。地址中的查询参数要完整保留。
-
更新订阅
回到「订阅分组」菜单,选择更新当前或全部订阅;菜单如区分通过代理与不通过代理,按当前网络的实际可达性选择,再查看更新日志。
-
导入单节点
复制完整的
vmess://或vless://链接,在主窗口使用「服务器」→「从剪贴板导入批量 URL」,常见快捷键为Ctrl+V。 -
核对连接项
打开节点编辑窗口,核对地址、端口、UUID、传输类型、路径与 TLS 服务器名称。导入成功只表示解析完成,不代表服务端可连接。
v2rayNG:订阅分组与剪贴板入口
- 订阅地址:打开右上角菜单 →「订阅分组设置」→「+」,填写备注和 URL;保存后回到主界面,执行菜单中的「更新订阅」。
- 分享链接:复制单条或多行链接,主界面「+」→「从剪贴板导入」,随后检查节点数量与备注。
- 完整 JSON:使用当前版本提供的自定义配置导入入口,不要用普通节点编辑表单代替。Android 运行方式与桌面本地 SOCKS 场景不同,不能直接照搬桌面入站后就假定能接管应用流量。
六、互转方案:按保留范围选择
“互转成功”至少要分为三个标准:文本可解码、客户端可导入、连接行为符合预期。前两项通过,仍可能丢失路由、DNS、指纹或传输扩展参数。先确定迁移目标,通常比先找一个转换按钮更省排查时间。
分享链接迁移节点
推荐通过客户端提供的分享或复制链接功能导出,再在目标客户端导入。完成后逐项核对传输与 TLS 参数;本地路由和 DNS 单独迁移。
适合:跨设备迁移单个节点、整理少量连接
订阅地址维护列表
在目标客户端重新添加订阅地址,交由其解析和更新。把正文转成静态链接列表只得到某一时刻的快照,不会自动保留远端刷新机制。
适合:节点经常调整、需要持续更新的分组
原生 JSON 保留策略
在兼容内核之间迁移配置,并逐项检查文件引用、端口、系统权限与字段支持情况。导入自定义配置后,部分客户端界面选项未必会作用于该配置。
适合:包含多个出站、自定义 DNS 或复杂路由
迁移后先检查日志是否出现配置解析或监听错误,再选择一个节点验证实际连接。桌面端还要检查系统代理或应用内代理是否指向真实入站;Android 端则确认连接服务已经启动,并按系统提示授予 VPN 接口权限。测速有结果和浏览器流量经过代理,是两个不同的验证动作。
七、导入与转换常见问答
订阅地址能打开,为什么更新后是零个节点?
先检查响应正文是否为 HTML 页面、错误信息或客户端不支持的格式。浏览器能访问 URL,不代表返回的是节点列表。确认令牌未失效,再查看客户端更新日志中的解析错误。
base64 解码后还是 vmess 开头,还要继续解码吗?
外层订阅已经解开。单行 vmess:// 后的内容在常见格式下还有一层编码,但应只解析协议前缀后的载荷,不要把整个多行列表再次整体解码。正常导入时由客户端完成这一层处理。
JSON 检查通过,为什么内核还是不能启动?
语法正确不等于字段合法。先区分 VMess 分享对象与完整配置,再检查内核是否支持协议和字段;若日志提示监听失败,核对本地端口是否被占用,而不是反复更换订阅编码。
转换成链接后,原来的分流规则怎么没了?
单节点链接通常只携带连接参数。需要恢复分流时,在目标客户端重建路由和 DNS,或者使用兼容的完整配置迁移方式。不要把缺少本地策略误认为节点认证参数丢失。
导入成功,但提示 TLS 或握手错误怎么办?
打开节点编辑页,对照服务端资料检查端口、传输类型、SNI、WebSocket Host 和路径,确认设备时间正常。不要用关闭证书验证来代替字段修正;若原始链接也失败,应继续排查服务端状态与网络连通性。