本文重點

先確認收到的是訂閱網址、編碼後的連結清單,還是完整的核心設定,再選擇正確的匯入方式。本文適合遇到「訂閱匯入後沒有內容」、「JSON 無法辨識」或「轉換後設定遺失」的使用者:從 VMess 與 VLESS 欄位開始,說明如何在本機轉換 Base64、匯入客戶端,以及將欄位對應至 Xray 設定,並整理分享連結無法保留的內容。

一、訂閱網址、Base64 與 JSON 的層級差異

「V2Ray 訂閱」並非單一的檔案格式。平時收到的 HTTPS 網址只是取得內容的入口;客戶端連線後才會收到實際回應。回應可能是每行一筆的分享連結,也可能是將整份連結清單以 Base64 編碼的文字。有些服務還會依據請求標頭回傳不同內容,因此不能只看網址的副檔名判斷格式。

項目辨識方式適用的處理方式
訂閱網址通常以 https:// 開頭,可能包含存取權杖填入訂閱群組,視需要更新
明文連結清單每行以 vmess:// 或 vless:// 等協定開頭從剪貼簿批次匯入
Base64 訂閱內容通常是一長串編碼字元,解碼後會出現分享連結交由訂閱解析器處理,或先在本機解碼
VMess 連結內的 JSON常見欄位包括 v、add、id、net用來產生或解析單筆 VMess 分享連結
Xray 原生設定常見的頂層欄位包括 inbounds、outbounds、routing交由相應的核心處理,或透過自訂設定入口載入

即使兩者都是 JSON,也不代表可以互換。VMess 分享物件描述單一伺服器及其傳輸參數;Xray 設定則描述核心如何監聽本機連接埠、建立輸出連線及執行路由。將前者存成 config.json,不會自動轉成後者;把後者整份做 Base64 編碼,也不會自動成為客戶端支援的訂閱。

二、VMess 與 VLESS 分享連結的欄位結構

常見的 VMess 分享格式是 vmess:// 加上一段 Base64,解碼後會得到 JSON。以下只展示 JSON 內容;所有網域名稱與 UUID 均為教學用虛構資料,無法用於連線。v: "2" 是這類分享物件的格式標記,不代表客戶端或核心版本。

{
  "v": "2",
  "ps": "VMess WS 範例",
  "add": "edge.example.com",
  "port": "443",
  "id": "00000000-0000-4000-8000-000000000001",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "edge.example.com",
  "path": "/ws",
  "tls": "tls",
  "sni": "edge.example.com"
}

add 是連線位址,port 是遠端連接埠,id 是使用者識別碼;net、host、path 分別用於傳輸方式與 WebSocket 請求設定。aid: "0" 對應目前常見的 VMess AEAD 設定,不應為了排除錯誤而任意改成其他數字。範例中的 type: "none" 也不是關閉 TLS 的開關。

VLESS 分享連結通常採用 URI 結構,識別資訊放在 @ 前,伺服器與連接埠放在後方,傳輸參數則寫在查詢字串中。以下同樣是無法連線的範例,連結應保持完整且位於同一行:

vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=edge.example.com#demo-vless

VMess 範例欄位

位址與連接埠
add 與 port
識別資訊
id
傳輸方式
net: "ws"
請求路徑
path: "/ws"
TLS 名稱
sni

這些是常見分享物件中的欄位;對應至核心設定時,欄位名稱與結構層級會有所不同。

VLESS 範例參數

使用者識別碼
URI 中 @ 前方的 UUID
協定加密
encryption=none
連線安全性
security=tls
傳輸方式
type=tcp
TLS 名稱
sni=edge.example.com

encryption=none 不代表停用 TLS;兩者屬於不同層級。

URI 參數值必須依 URL 規則編碼。例如,路徑 /ws?ed=2048 作為單一參數值時,應寫成 path=%2Fws%3Fed%3D2048,避免其中的問號被誤認為另一層查詢字串。備註中的中文、空格與特殊符號也應正確編碼。請勿將整條 URI 一次進行百分比編碼,否則協定開頭與分隔符號也會遭到破壞。

三、在本機解碼與重新編碼 Base64 訂閱

常見的轉換流程是「多筆分享連結 → 以換行符號串接 → 將整段文字進行 Base64 編碼」。如果其中包含 VMess,就會有兩層編碼:外層包住連結清單,內層則包住單筆 VMess 的 JSON。解開外層後若已看到 vmess://,就應按行拆分,而不是繼續將整段含有協定開頭的內容當成 Base64 解碼。

3 → 4
Base64 每 3 個位元組對應 4 個字元,不計分隔用的換行
443
本文範例中的遠端 TLS 連接埠,不代表所有節點
10808
後續設定的本機 SOCKS 連接埠,使用前請確認沒有被占用

以下原生 JavaScript 可在本機空白頁面的開發者工具主控台執行。請先閱讀程式碼,只將自己的資料放入本機變數;程式不會發出網路請求。編碼函式採用 UTF-8,避免中文備註直接傳入 btoa() 時發生錯誤;解碼函式則同時處理標準 Base64 與常見的 URL 安全字元變體。

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(text) {
  let encoded = text.trim()
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(encoded)) {
    throw new Error("內容不是有效的 Base64 字元序列");
  }

  encoded = encoded.replace(/=+$/, "");
  if (encoded.length % 4 === 1) {
    throw new Error("Base64 長度異常,請確認是否複製完整");
  }

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

const demoLink =
  "vless://[email protected]:443"
  + "?encryption=none&security=tls&type=tcp&sni=edge.example.com#demo-vless";

const encodedDemo = encodeSubscription(demoLink);
console.log(encodedDemo);
console.log(decodeSubscription(encodedDemo));

四、v2rayN 與 v2rayNG 的匯入方式

選擇匯入方式時,先確認「手上有什麼」。訂閱網址要加入訂閱群組,單筆或多筆分享連結可從剪貼簿匯入,完整的核心 JSON 則要透過自訂設定匯入。桌面版與 Android 版的選單位置可能隨版本調整,以下使用常見的中文選單名稱;若介面文字略有不同,請以相應的匯入功能為準,別把訂閱網址填入伺服器位址欄。

v2rayN:先新增群組,再更新訂閱

  1. 建立群組

    在主視窗開啟「訂閱分組」→「訂閱分組設定」,點選「新增」建立群組,填入備註與訂閱網址。儲存後返回伺服器清單。

  2. 取得內容

    在「訂閱分組」選單中選擇「更新目前訂閱(不透過代理)」或相應的透過代理更新選項。如果目前網路可直接連線至訂閱服務,請先選前者;使用後者則需要已有可用的代理及正確的代理連線路徑。

  3. 匯入連結

    如果手上只有分享文字,請複製完整連結,再選擇「伺服器」→「從剪貼簿匯入批次 URL」進行匯入;常見的桌面介面也可使用 Ctrl+V。此方式新增的是節點快照,不會建立遠端訂閱更新關係。

  4. 確認參數

    開啟已匯入項目的編輯視窗,檢查伺服器位址、連接埠、傳輸協定、TLS 與 SNI。清單中出現項目還不夠,請啟動該項目,並檢查底部的核心記錄是否有設定解析錯誤。

v2rayNG:分別處理訂閱與剪貼簿匯入

如果解碼訂閱後改用手動匯入,日後伺服器端變更位址、連接埠或識別資訊時,本機快照不會自動同步。若需要持續更新,請保留原本的訂閱群組;搬移時也應分別備份訂閱網址與本機自訂設定,不要只留一份分享連結清單。

五、將分享連結對應至 Xray 原生 JSON

客戶端產生核心設定時,不只是更改欄位名稱,還會加入本機入站、出站標籤、記錄與路由等執行資訊。以下將前述 VLESS TCP + TLS 範例對應成最精簡的 SOCKS 設定:本機只監聽 127.0.0.1:10808,遠端仍是教學用網域,因此僅供理解結構,無法直接連線。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "edge.example.com",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-4000-8000-000000000001",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "edge.example.com"
        }
      }
    }
  ]
}
分享連結內容JSON 對應位置轉換注意事項
伺服器與 :443settings.vnext[0].address 與 portJSON 中的連接埠使用數字
UUIDsettings.vnext[0].users[0].id保留完整內容,不能以備註取代
encryption=noneusers[0].encryption屬於 VLESS 使用者設定,不是 TLS 設定
type=tcpstreamSettings.network目前使用的核心必須支援該傳輸名稱與語法
security=tls 與 snistreamSettings.security 與 tlsSettings.serverName不應根據伺服器 IP 猜測 SNI
#demo-vless通常會存為客戶端備註備註不一定會寫入執行設定

此處設定的本機連接埠 10808 僅為範例,不代表所有客戶端目前都使用此連接埠。執行前請確認連接埠沒有被其他程式占用。只監聽回送位址可避免未設定驗證的 SOCKS 入站暴露於區域網路;也不要為了解決遠端連線問題,就改成監聽所有網路介面。

將完整 JSON 反向匯出為分享連結時,通常只能擷取一個相容的代理輸出。routing.rules、DNS、多個入站與多個輸出之間的組合關係,無法透過單一節點分享連結完整表達。如果原始設定依賴這些項目,應保留 JSON;匯出一個 QR Code 並不代表完成完整搬移。

六、匯入清單為空、解碼錯誤與轉換後欄位遺失

排查時應依照「取得 → 解碼 → 解析 → 執行」分層記錄結果。訂閱更新成功只表示客戶端完成某次處理;是否產生項目、欄位是否完整、核心是否啟動,以及遠端是否可連線,仍是不同的檢查項目。請先修正最早發生問題的步驟,避免同時修改 TLS、連接埠與訂閱網址,導致無法比較。

訂閱網址能開啟,為什麼匯入後清單是空的?

請檢查實際收到的內容,而不只是確認請求是否成功。如果收到網頁、權限提示,或目前客戶端不支援的格式,請向訂閱服務提供者確認適用格式;如果解碼後出現分享連結,可將其中一筆完整複製到剪貼簿匯入入口測試,藉此區分是回應格式還是單筆連結有問題。

Base64 解碼顯示字元或長度不正確,該怎麼辦?

先確認沒有把訂閱網址本身拿來解碼,也沒有連同引號、程式碼區塊標記或省略號一起貼入。移除正文中的分隔空白,並檢查 URL 安全字元與尾端補位字元。如果內容已遭截斷,只補上幾個等號無法還原遺失資料,請重新取得完整內容。

JSON 通過語法檢查,為什麼核心仍然報錯?

語法正確只表示逗號、引號與括號符合規則,不代表核心支援其中的欄位結構。先確認它是 Xray 執行設定,而非 VMess 分享物件;接著查看核心記錄指出的欄位、傳輸類型與缺少的檔案,確認匯入的設定是否符合實際使用的核心。

匯出後再匯入,為什麼節點名稱相同卻無法連線?

名稱不是連線參數。請逐一比對位址、連接埠、UUID、傳輸方式、路徑、Host、SNI,以及有使用時的 Flow 與 Reality 參數。不要以關閉憑證驗證取代逐項檢查;如果匯出工具遺漏必要欄位,請改用完整設定備份或原始訂閱還原。

本機修改過的節點,更新訂閱後為什麼又還原了?

更新訂閱時通常會依遠端內容重新整理所屬項目,本機修改不一定會保留。需要獨立維護的項目,請複製到非訂閱群組並清楚記錄修改內容;仍由伺服器端管理的節點,則優先從訂閱來源修正,避免每次更新後都要重新手動調整。

七、轉換後的驗證與備份順序

最穩妥的搬移方式,不是只保存「一串看起來很長的文字」,而是分別保留三種用途明確的資料:供日後更新的原始訂閱網址、用於交換節點的分享連結,以及用來還原本機設定的完整設定檔或客戶端備份。三者可以同時保存,但不能互相取代;含有識別資訊的備份應存放在設有存取控制的本機位置。

  1. 保留原始資料:轉換前先保存原始回應或原始檔案,避免最後只剩經過多次處理的版本。
  2. 確認單筆資料:先選一筆項目,比對協定、位址、連接埠與傳輸參數,確認沒有混淆 UUID、Host 與 SNI。
  3. 檢查啟動狀況:啟用項目並查看核心記錄;先排除設定解析錯誤與連接埠占用,再處理憑證、交握與遠端連線問題。
  4. 檢查應用程式設定:桌面應用程式還需正確設定系統代理或指定的本機代理連接埠;Android 端則需確認連線已啟動,並授予系統要求的 VPN 權限。
  5. 確認訂閱更新:如果搬移需求包含訂閱,請在目標客戶端手動更新一次,確認新增內容進入預期群組,而非只留下一批靜態節點。