訂閱格式解析:base64、原生 JSON 與分享連結如何互相轉換

訂閱網址開啟後是一串亂碼,vmess 連結匯入後節點名稱變成問號,手寫 JSON 少一個欄位就連不上。三種格式的界線在哪裡、轉換時哪一步最容易遺漏欄位,本文依欄位逐條對照。

本文速覽

把 base64 訂閱、原生 JSON 設定與 vmess、vless 分享連結三種格式拆開對照,給出「訂閱 → 連結清單 → 單一節點欄位 → 原生 JSON」的完整轉換路徑,並列出轉換過程中最容易遺失的欄位。適合已經能連上節點、需要手動修改設定或跨用戶端移轉的讀者。

三種格式分別是什麼

同一組節點資訊,放進不同載體後長得完全不一樣。base64 訂閱是批次清單,原生 JSON 是完整設定,分享連結是單筆記錄。

三者的資訊量並不對等:訂閱裡的一條連結通常只描述一個出站(outbound),而原生 JSON 還要額外承擔入站、路由、DNS、日誌這些用戶端側設定。混淆這一點,是後面所有轉換問題的起點。

維度base64 訂閱原生 JSON分享連結
承載內容多行分享連結完整設定,含出站、入站與路由單一節點的連線參數
自動更新用戶端定時拉取手動替換檔案不支援
典型來源面板批次匯出伺服器端設定檔或手動撰寫用戶端、面板單筆複製
適用情境多裝置共用一份節點清單精細分流與固定本機連接埠臨時匯入、跨用戶端移轉
1 次
訂閱整體解碼次數
2 層
vmess 節點總解碼層數
443
TLS 與 Reality 常用連接埠
0
VMess 的 alterId 預設值

base64 訂閱的編碼規則

base64 訂閱只多一層編碼:伺服器端把多行分享連結拼成純文字,整體做一次 base64,再作為 HTTP 回應傳回。用戶端拉取後先解碼,拿到每行一條的連結清單。

解碼失敗時,用戶端會退回以明文處理,所以同一套解析邏輯能同時處理 base64 與明文兩種訂閱。自己動手解碼時,記住下面這條指令就夠。

# 訂閱回傳的原文存成 sub.txt,整體解碼一次
base64 -d sub.txt > nodes.txt    # GNU coreutils
base64 -D sub.txt > nodes.txt    # macOS / BSD

wc -l nodes.txt                  # 行數一般等於節點條數
head -n 2 nodes.txt

解碼結果裡每行開頭就是協議前綴,常見的是 vmess://vless://。同一條訂閱混用多種前綴是正常的,用戶端會按行逐條解析。

如果解出來的第一行不是 vmess:// 也不是 vless://,代表原文本來就是明文訂閱,不需要再解。

分享連結的欄位結構

vmess 與 vless 的差別在編碼方式:vmess 連結是「base64 包一層 JSON」,vless 連結是「URI 加查詢參數」。前者解出來的欄位名稱全是縮寫,後者直接在網址列就能讀。

vmess:// 後面的整段 base64 解一次,得到的是下面這個物件:

{
  "v": "2",              // 連結格式版本,固定為 2
  "ps": "香港-01",      // 備註,匯入後作為節點名稱
  "add": "example.com", // 伺服器位址
  "port": "443",        // 連接埠,這裡是字串
  "id": "b831381d-6324-4d53-ad4f-8cda48b30811",
  "aid": "0",           // alterId,僅 VMess 有
  "scy": "auto",        // 加密方式
  "net": "ws",          // 傳輸層
  "type": "none",       // 偽裝類型
  "host": "example.com", // WS 的 Host 標頭
  "path": "/ws",       // WS 路徑
  "tls": "tls"          // 是否啟用 TLS
}

vless 連結沒有內層 base64,所有參數都寫在 ? 之後的查詢字串裡,# 之後是備註。參數名稱比 vmess 的縮寫更直觀,但要按 URI 規則做 URL 編碼。

vless://[email protected]:443?encryption=none&security=reality&sni=www.example.com&fp=chrome&pbk=UuMBgl8KtNqHqY7p&sid=0123abcd&flow=xtls-rprx-vision&type=tcp#香港-01

兩種連結描述的是同一件事,只是欄位名稱和擺放位置不同。下面四張卡片把常用欄位、原生 JSON 的頂層結構與本機連接埠慣例放在一起對照。

vmess 連結欄位

add / port
位址與連接埠,port 是字串
id / aid
UUID 與 alterId
scy
加密方式,常用 auto 或 none
net / type
傳輸層與偽裝類型
path / host
WS 路徑與 Host 標頭

整段是 base64(JSON),解一次即可讀。

vless 連結參數

encryption
固定為 none,不可省略
security
none / tls / reality
sni
TLS 憑證網域名稱
flow
Reality 節點填 xtls-rprx-vision
pbk / sid
Reality 公鑰與短 ID

參數寫在查詢字串裡,注意 URL 編碼。

原生 JSON 頂層

inbounds
本機監聽,如 SOCKS 10808
outbounds
出站節點,含 tag 與 streamSettings
routing
分流規則,依 outboundTag 指向出站
dns
解析方式與上游伺服器
log
日誌等級,排查時用 debug

欄位名稱區分大小寫,port 必須是數字。

本機連接埠慣例

SOCKS
10808
HTTP
10809
日誌等級
warning / debug
出站 tag
proxy、direct、block 三個常用名稱

連接埠與 tag 由本機設定決定,與訂閱無關。

三種格式怎麼互相轉換

轉換路徑固定為四步:訂閱解出連結清單,連結還原成欄位,欄位再拼成原生 JSON。反向走一遍就是匯出。

  1. 取出訂閱原文

    用瀏覽器開啟訂閱網址,把回傳內容整段存成 sub.txt。回傳的可能是一整段 base64,也可能是明文連結清單。

  2. 解出連結清單

    執行 base64 -d sub.txt > nodes.txt,得到每行一條的分享連結;協議前綴在行首,備註在行尾 # 之後。

  3. 還原單一節點

    vmess 要把 vmess:// 後的內容再解一次 base64 得到 JSON;vless 直接讀 ? 後的查詢參數,不需要再解碼。

  4. 拼成原生 JSON

    把欄位填進 outboundsvnextstreamSettingsport 改成數字,tag 自己命名,address 不帶協議前綴。

第四步拼出來的出站大致長這樣,欄位與上面的 vless 連結一一對應:

{
  "outbounds": [{
    "tag": "proxy",
    "protocol": "vless",
    "settings": {
      "vnext": [{
        "address": "example.com",
        "port": 443,
        "users": [{
          "id": "b831381d-6324-4d53-ad4f-8cda48b30811",
          "encryption": "none",
          "flow": "xtls-rprx-vision"
        }]
      }]
    },
    "streamSettings": {
      "network": "tcp",
      "security": "reality",
      "realitySettings": {
        "serverName": "www.example.com",
        "publicKey": "UuMBgl8KtNqHqY7p",
        "shortId": "0123abcd",
        "fingerprint": "chrome"
      }
    }
  }] // 出站陣列
}

反向轉換同理:原生 JSON 裡的 settings.vnext[0]streamSettings 就是連結參數的展開形式,把 addressportid 取出來,再按協議規則編碼回 URI 即可。VMess 還要把 alterId 寫回 aid

用戶端裡還有兩條更省事的路徑:v2rayN 支援「自訂設定」類型的伺服器,把完整 JSON 貼進設定框後核心直接讀取,不再由用戶端拼裝出站;反過來,從訂閱清單複製單一節點的分享連結,可以直接貼到另一台裝置的 v2rayNG 裡,走「⋮」→「從剪貼簿匯入設定」。

轉換時最容易遺漏的欄位

掉欄位幾乎都發生在手動搬運的環節:複製貼上時被截斷、字串與數字混用、縮寫看漏一個字母。下面這些位置逐條對一遍,能涵蓋大部分「匯入成功但連不上」的情況。

注意

手動修改原生 JSON 時,儲存前先用編輯器跑一次 JSON 語法檢查,尾隨逗號與缺少的引號是最常見的兩類錯誤。排查階段先把 log.loglevel 設為 debug,讓核心把出錯欄位寫進日誌,定位完再改回 warning

什麼情境該用哪一種

三種格式沒有優劣,只有分工。判斷依據只有兩條:節點清單會不會變,以及本機需不需要分流規則。

選擇依據:節點是否會變、是否需要本機分流

base64 訂閱
  • 一條網址管理全部節點
  • 換裝置只填一次,清單自動同步
  • 節點增刪由伺服器端決定,本機不用改
  • 適合多裝置、節點會調整的情境
原生 JSON
  • 可以寫 routing 分流規則與 DNS 策略
  • 本機 SOCKS 10808、HTTP 10809 連接埠固定
  • 節點異動要手動替換檔案
  • 適合單機、需要精細控制的情境

兩者可以並存:訂閱負責節點清單,原生 JSON 裡的 routing 負責決定哪些流量走代理。

分享連結則居中:它比訂閱更適合臨時匯入,比原生 JSON 更適合跨用戶端複製。同一條連結貼進 v2rayN 與 v2rayNG,得到的出站參數是一樣的,差別只在用戶端把本機連接埠與分流規則放在自己的設定裡。

實際使用中更常見的組合是:伺服器端維護一條訂閱網址,用戶端裡再補一份本機路由規則。節點跟隨訂閱更新,分流邏輯留在本機,兩邊互不干擾。

常見問題

訂閱網址在瀏覽器裡開啟是一串亂碼?

那是 base64 原文,不是出錯。整段複製下來解一次,或直接把網址填進用戶端的訂閱設定裡更新。

vmess 連結匯入後節點名稱變成問號?

ps 欄位是 UTF-8 中文,解碼工具以 GBK 處理就會亂碼。改用 UTF-8 重新解一次再匯入。

vless 連結匯入後提示缺少 flow?

Reality 節點要在 flow 裡填 xtls-rprx-vision,同時補齊 pbksidfp 三組參數。

自己寫的 JSON 被判為無效設定?

先查尾隨逗號與引號,再把 port 從字串改成數字,最後核對 routing.rules[].outboundTag 與出站的 tag 是否一致。

三種格式的轉換關係並不複雜:訂閱解一層得到連結,vmess 連結再解一層得到欄位,欄位展開就是原生 JSON。真正費時間的從來不是解碼,而是把欄位一個不漏地放到正確位置。

下載 v2rayN / v2rayNG

Windows、macOS、Linux 桌面版與 Android 版的入口在下載頁;訂閱匯入與分流設定請見教學。

下載用戶端