V2Ray 訂閱格式比較:Base64 訂閱、原生 JSON 與 vmess:// 分享連結互轉

整理三種常見訂閱與節點格式的差異,說明如何解碼 Base64、解析分享連結並轉成原生 JSON 設定,也介紹各款用戶端支援的格式。

本文重點

Base64 是編碼方式,訂閱是取得節點集合的方法,原生 JSON 則是核心執行設定,三者並非同一層級。本文適合遇到「訂閱能開啟卻無法匯入」、「解碼後仍是一串字元」或「分享連結不能當成設定檔使用」的讀者。依序檢查外層訂閱、單筆連結與核心欄位,就能判斷該解碼、匯入還是補齊設定。

先釐清三種格式:訂閱網址不是節點設定

結論:先確認取得的內容,再選擇匯入方式。以 https:// 開頭的訂閱網址只是取得內容的入口;回應本文才會決定用戶端收到的是 Base64 節點清單、明文分享連結,還是其他格式。直接對網址本身進行 Base64 解碼,不會得到伺服器設定。

訂閱網址與節點清單

推薦

常見的回應內容是多筆分享連結逐行排列,再將整份內容進行 Base64 編碼。用戶端會儲存訂閱網址,更新時重新取得節點;這種方式適合持續維護節點清單,但並非所有服務都採用相同格式。

適用情境:服務提供有效的訂閱網址,且需要持續更新節點。

vmess:// 分享連結

本文討論常見的 v2 分享格式:前綴後方是以 Base64 編碼的節點 JSON。內容主要描述單一 VMess 出站所需資訊,不包含完整的本機監聽、DNS 與路由策略。

適用情境:移轉單一節點、從剪貼簿匯入,以及透過 QR Code 傳送。

核心原生 JSON

通常包含 inbounds、outbounds,也可設定 dns 與 routing。結構與支援欄位依核心及版本而異,不能只看副檔名判斷是否相容。

適用情境:自訂入站、路由規則,以及指定核心的設定管理。

Base64 不具保密功能。訂閱網址中的存取權杖、節點 UUID 和分享 QR Code 都可能讓他人取得連線權限。排查問題時請使用本機編輯器,不要將真實內容貼到線上解碼網站;提供記錄檔給他人前,也應移除這些識別資訊。

Base64 訂閱解碼:分別處理外層清單與內層節點

常見的兩層結構如下:先解碼外層 Base64,取得多筆 vmess:// 連結;再選取其中一筆,移除前綴並再次解碼,才會得到節點 JSON。不能對所有輸入一律解碼兩次。若訂閱本文已直接以分享連結開頭,外層就不需要解碼。

  1. 取得回應本文

    使用本機工具檢視訂閱回傳的內容。如果看到登入頁面、驗證碼或錯誤頁面,請先處理存取問題;HTML 頁面不是節點清單,即使請求成功也不代表訂閱可用。

  2. 辨識外層格式

    如果本文直接出現 vmess:// 或 vless://,請逐行讀取。若內容是連續的編碼字串,可嘗試進行 Base64 解碼;若以 { 或 [ 開頭,請先按 JSON 格式檢查。

  3. 分離節點列

    將解碼結果依換行拆分,移除每行前後空白並篩除空行。不要把多筆連結合併成一筆,也不要更動連結內的字元。

  4. 解析單筆連結

    針對本文所述的 VMess v2 格式,移除 vmess:// 前綴後進行解碼,再解析 JSON。若內容不是這種結構,請確認分享格式的來源,不要硬套欄位。

以下函式可在本機瀏覽器主控台使用,支援標準 Base64 與常見的 URL 安全字元,會補上省略的尾端填充,並以 UTF-8 還原中文備註。執行前請先閱讀程式碼。函式不會傳送網路請求,也不會自動讀取剪貼簿。

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

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {
    throw new Error("輸入包含非 Base64 字元");
  }

  value = value.replace(/=+$/, "");
  if (value.length % 4 === 1) {
    throw new Error("Base64 長度不完整");
  }

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

function readSubscription(body) {
  const text = body.trim();
  const decoded = /^(vmess|vless):\/\//i.test(text)
    ? text
    : decodeBase64Utf8(text);

  return decoded.split(/\r?\n/)
    .map(line => line.trim())
    .filter(Boolean);
}

function readVmess(link) {
  const value = link.trim();
  if (!value.startsWith("vmess://")) {
    throw new Error("需要 vmess:// 連結");
  }
  return JSON.parse(decodeBase64Utf8(value.slice(8)));
}

readSubscription 僅示範「明文連結清單或其 Base64 編碼」這一種訂閱格式,並非通用訂閱解析器。遇到其他結構時請停止操作,並查看服務提供者的格式說明。Base64 解碼成功只表示內容可讀,不代表節點有效或帳號仍有使用權限。

解析 vmess://:分享欄位如何對應原生設定

以下是用於說明結構的 VMess v2 節點物件。example.com 是文件專用的示例網域,UUID 也僅供示範,無法用來連線至代理伺服器。欄位 v 的值 "2" 代表分享格式版本,不是用戶端或核心版本。

{
  "v": "2",
  "ps": "文件範例",
  "add": "example.com",
  "port": "443",
  "id": "00000000-0000-4000-8000-000000000001",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.com",
  "path": "/ws",
  "tls": "tls",
  "sni": "example.com"
}
分享欄位原生出站位置轉換注意事項
add、portsettings.vnext[].address、port位址是字串;原生設定中的連接埠則使用數字。
id、aidsettings.vnext[].users[].id、alterId本例的 aid 為 0,對應現代 VMess AEAD 用法。
scysettings.vnext[].users[].security這是 VMess 使用者加密設定,不是 TLS 開關。
netstreamSettings.network本例使用 ws;不同傳輸方式不能只修改單一欄位。
host、pathwsSettings.headers.Host、wsSettings.path此處按 WebSocket 解讀,路徑中的查詢參數也必須保留。
tls、snistreamSettings.security、tlsSettings.serverNameTLS 伺服器名稱與 WebSocket Host 屬於不同層級。
ps、v備註與分享格式資訊這不是核心連線所需欄位,不應原封不動地放入出站設定。

轉換判斷:先保留傳輸語意,再調整欄位型別

逐項核對位址、連接埠、UUID、傳輸方式、TLS、SNI、Host 與路徑。不要把分享欄位 type: "none" 當成關閉 TLS 的依據,也不要用位址欄位自動覆蓋服務提供者明確指定的 SNI。

VMess 與 VLESS 是不同的通訊協定。vless:// 常見格式是包含使用者資訊、主機、連接埠與查詢參數的 URI,不能照搬「移除前綴後將 Base64 解碼成 JSON」的流程。將連結前綴從 VMess 改成 VLESS,也不會完成協定轉換;伺服器必須支援相應協定與身分設定。

轉成原生 JSON:除了節點,也要補齊入站設定

原生設定並不是將解碼後的節點 JSON 換個檔名。以下提供 Xray 常見的 VMess、WebSocket、TLS 完整範例:本機提供 SOCKS 入站,出站使用上方的示範節點。實際欄位仍須依照安裝的核心版本確認;這不代表所有 V2Fly 版本都接受相同設定。

10808
本例的本機 SOCKS 監聽連接埠
443
本例的遠端 TLS 連線連接埠
0
本例的 VMess alterId 數值
{
  "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": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-4000-8000-000000000001",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.com",
          "allowInsecure": false
        },
        "wsSettings": {
          "path": "/ws",
          "headers": {
            "Host": "example.com"
          }
        }
      }
    }
  ]
}

此範例未加入分流規則,預設會將流量交由第一個出站處理。它也不會自動設定系統代理;應用程式必須明確使用 127.0.0.1:10808 的 SOCKS 服務。127.0.0.1 會將監聽範圍限制在本機,排查問題時不應直接改成對所有網路介面開放的位址。

反向轉換:分享連結只能帶走部分設定

若要從單一 VMess 出站產生分享連結,需先從原生設定擷取伺服器、使用者與傳輸欄位,組成前述的 v2 分享物件,再以 UTF-8 編碼成 Base64,最後加上 vmess:// 前綴。不能直接將整份原生設定編碼後加上此前綴,因為產生的格式不符合常見的節點匯入慣例。

function encodeBase64Utf8(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  for (const byte of bytes) {
    binary += String.fromCharCode(byte);
  }
  return btoa(binary);
}

function createVmessLink(share) {
  return "vmess://" + encodeBase64Utf8(JSON.stringify(share));
}

function createBase64Subscription(links) {
  return encodeBase64Utf8(links.join("\n"));
}

createVmessLink 接收的是依照欄位表整理好的分享物件,不會自動擷取複雜設定,也不會驗證節點參數。createBase64Subscription 接收分享連結陣列,並產生常見格式的訂閱本文;它不會建立可更新的訂閱網址,後者仍須由受控服務提供回應。

移轉判斷:節點用連結,策略用備份

只需移轉伺服器連線資訊時,使用分享連結;需要保留路由、DNS 與本機監聽設定時,使用經過檢查的設定備份。轉換後逐項核對重要欄位,不要以「匯入成功」作為完整無損移轉的證明。

用戶端匯入:分開使用訂閱、剪貼簿與自訂設定

用戶端能辨識某種外層格式,不代表其核心支援其中所有協定與傳輸方式。v2rayN 是桌面用戶端;v2rayNG 使用 Xray 核心;v2flyNG 使用 V2Fly 核心。請先確認連線參數與核心功能相符,再選擇匯入方式。以下選單以常見的中文介面為參考,不同發行版本的名稱與位置可能有所不同。

輸入內容v2rayNAndroid 用戶端
訂閱網址前往「訂閱分組」→「訂閱分組設定」,新增網址後更新分組。在 v2rayNG 側邊欄的「訂閱分組設定」新增網址,再從主畫面選單點選「更新訂閱」。v2flyNG 請依目前版本的訂閱入口操作。
單筆分享連結複製完整連結,選擇「伺服器」→「從剪貼簿匯入批次 URL」。在 v2rayNG 主畫面右上角點選「+」→「從剪貼簿匯入」。v2flyNG 請使用分享連結匯入功能。
原生 JSON 檔案使用「伺服器」選單中的「新增自訂設定伺服器」,並確認所使用的核心。使用目前版本的自訂設定匯入功能;不要將內容貼到訂閱網址欄位,跨核心移轉前請先檢查欄位。

v2rayN 常見的訂閱更新操作位於「訂閱分組」→「更新目前訂閱(不透過代理)」。此選項控制取得訂閱時是否經由代理,不會將節點的連線方式改成直連。若訂閱網站必須透過代理存取,請選擇相應的透過代理更新方式,並先確認目前的代理連線正常。

  1. 更新失敗先檢查回應內容。網址過期、存取權杖失效或回傳網頁時,不應繼續轉換節點格式。請先檢查更新記錄與訂閱權限。
  2. 匯入失敗先檢查結構。確認是否多複製了引號、缺少前綴,或誤將完整 JSON 當成分享連結。若中文備註出現亂碼,請檢查 UTF-8 編碼與解碼。
  3. 連線失敗再檢查參數。節點已出現在清單中卻無法連線時,請核對 UUID、連接埠、WebSocket 路徑、Host、TLS 與 SNI,不要反覆重新進行 Base64 編碼。
  4. 手動修改請另行儲存。更新訂閱可能會重建節點項目。臨時修改的節點適合複製到獨立分組,並記錄與訂閱原始值之間的差異。

常見問題:解碼成功,為什麼仍無法使用?

解碼後仍是 vmess://,代表解碼失敗嗎?

不是。外層訂閱包含分享連結清單,看到 vmess:// 通常表示已取得節點列。若要查看節點 JSON,請再解碼單筆連結前綴後方的內容;若只是要匯入用戶端,通常可直接使用完整分享連結。

任何 JSON 都能當作 V2Ray 原生設定嗎?

不行。VMess 分享物件、用戶端設定備份與核心設定都可能使用 JSON,但欄位意義各不相同。請先確認是否具備該核心要求的入站、出站結構,再檢查協定與傳輸欄位。JSON 語法正確,只代表文字格式可以解析。

將本機節點清單編碼後,就能建立可自動更新的訂閱嗎?

這只有訂閱本文,並沒有訂閱服務。自動更新還需要穩定且具備存取控制的取得網址。將本文存到本機,不會讓其他裝置自動收到變更;若只需傳送一次節點,分享連結更直接。

用戶端匯入成功,代表連線參數完整嗎?

不一定。解析器可能接受基本欄位,卻忽略不支援的擴充參數。匯入後請開啟節點編輯畫面,核對傳輸類型、路徑、Host 與 TLS 伺服器名稱,再實際測試連線。QR Code 也只是文字載體,不會補上缺少的參數。

下載v2rayN查看平台與安裝選項